RSpec测试返回收藏的帖子

时间:2015-04-25 06:06:25

标签: ruby-on-rails ruby rspec

我是Ruby on Rails的新手,目前正在Bloc.io的一门课程中注册,该课程的任务是创建RSpec测试,返回一个帖子是否被特定用户收藏。

这是我目前的RSpec文件:

require 'rails_helper'

describe User do

 include TestFactories

 describe "#favorited(post)" do

   before do
     @post = associated_post
     @user = authenticated_user
   end

   it "returns `nil` if the user has not favorited the post" do
     expect( @user.favorited(@post) ).to be_nil
   end

   it "returns the appropriate favorite if it exists" do
     favorite = Favorite.new
     expect( @user.favorite ).to eq( favorited(@post) )
   end

   it "returns `nil` if the user has favorited another post" do

   end
  end
 end 

我成功通过了第一次测试(it "returns 'nil' if the user has not favorited the post"),但我对如何通过第二次和第三次测试感到困惑。

我认为我目前为第二次测试(it "returns 'nil' if the user has not favorited the post")启动的内容是正确的,并且相信我需要向Favorite.new提供一个哈希,将其分配给帖子和用户,但是不确定需要传递什么。

这是我收录的TestFactories文件,只是有帮助:

module TestFactories

 def associated_post(options={})
   post_options = {
     title: 'Post title',
     body: 'Post bodies must be pretty long.',
     topic: Topic.create(name: 'Topic name'),
     user: authenticated_user
     }.merge(options)

    Post.create(post_options)
 end

 def authenticated_user(options={})
   user_options = {email: 'email#{rand}@fake.com', password: 'password'}.merge(options)
   user = User.new(user_options)
   user.skip_confirmation!
   user.save
   user
 end

end

以及我的#favorited(post)方法:

def favorited(post)
  favorites.where(post_id: post.id).first
end

编辑:

以下是最喜欢的型号:

class Favorite < ActiveRecord::Base
  belongs_to :post
  belongs_to :user
end

第二次编辑:

我能够为我的第二次测试改变一些代码:

it "returns the appropriate favorite if it exists" do
  favorite = Favorite.create(user: @user, post: @post)
  expect( @user.favorited(@post) ).to eq( favorite )
end

我现在收到以下失败/错误:

Failures:

1) User#favorited(post) returns the appropriate favorite if it exists
   Failure/Error: expect( @user.favorited(@post) ).to eq( favorite )

   expected: #<Favorite id: 1, post_id: 1, user_id: nil, created_at: "2015-04-26 04:16:37", updated_at: "2015-04-26 04:16:37">
        got: nil

   (compared using ==)
 # ./spec/models/user_spec.rb:20:in `block (3 levels) in <top (required)>'

Finished in 0.53769 seconds (files took 3.21 seconds to load)
3 examples, 1 failure, 1 pending

Failed examples:

rspec ./spec/models/user_spec.rb:18 # User#favorited(post) returns the appropriate favorite if it exists

在我看来,测试在查找指定用户的ID时遇到问题。我该如何定位和分配指定用户的ID?

有什么想法可以引导我朝着正确的方向前进吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

让我们来看看你的第二个测试用例:

it "returns the appropriate favorite if it exists" do
  favorite = Favorite.new
  expect( @user.favorite ).to eq( favorited(@post) )
end

首先,您需要create Favorite,而不仅仅是new。使用create会将其保存到数据库中,这将允许User#favorite找到它。

其次,您需要将Favorite与您的UserPost相关联。

favorite = Favorite.create(user: @user, post: @post)

(这假设您的Favorite模型与belongs_toUserPost个关联。)

接下来,让我们来看看你的期望。您可能需要reload @user模型,以确保它获取新的favorite

expect(@user.reload.favorite).to eq(favorited(@post))

答案 1 :(得分:0)

如果您的目标是测试以下方法:

class User < ActiveRecord:Base

  def favorited(post)
    ...
  end

end

然后我会建议做类似以下的事情:

it "returns the appropriate favorite if it exists" do
  favorite = Favorite.create( user_id: @user.id, post_id: @post.id )

  expect( @user.favorited( @post ) ).to eq( favorite )
end

例外内容如下:

我希望实际值 @ user.favorited(@ post)等于预期值收藏。因此,我建议在使用 expect 语法时遵循此模式:

expect( actual_value ).to eq( expected_value )

在这种情况下, actual_value 表示执行User#favorited under test(UT)的结果,而 expected_value 表示我们认为在执行之前应该执行的操作测试。最后,我喜欢在将参数传递给创建方法时要明确,因为Rails倾向于做这些神奇的事情,而这些事情对于代码的读者来说可能并不总是很清楚。