rspec期望语法与validates_associated

时间:2013-06-29 05:36:45

标签: ruby-on-rails ruby rspec tdd factory-bot

rspec的新手,想知道如何为validates_associated写一个期望。

post.rb

class Post
  validates_associated :user
end

post_spec.rb

it 'must belong to a user' do
  post = build(:post, user: nil)
  expect(post).to have(1).errors_on(:user)
end

然而,这不起作用,也没有检查error_on(:user_id)

2 个答案:

答案 0 :(得分:1)

class Post
  validates_associated :user
end

class User
  validates :name, presence:true
end

validates associated practically means with example


post = Post.find 1

post.title = "something"
post.user.name =  nil

post.save => false

it returns false as associated user is not valid because user's name
is not present.

to test it, you should do 

it 'validates associated user' do
  post = build(:post)
  post.user.build(:name => nil)
  post.save.should == false
  post.user.errors.should == {:name => [name must be present]} // something like this
end

答案 1 :(得分:0)

有很多方法可以使用RSpec,特别是考虑到最近从shouldexpect方法的转变。在这个答案中,我将尝试回答为什么你的测试不能正常工作,假设用这些特定参数调用的构建确实会引发你说它应该的错误。换句话说,我会尝试回应你的测试形式。

首先,我不确定您的陈述post = build(...)的意图。如果您打算在那时实际执行构建方法,并且您希望构建的执行失败,那将导致您的测试失败。要测试引发错误,您需要将将引发错误的代码传递给RSpec并让RSpec调用它。通常,您希望在执行测试代码之前设置期望

如果您希望post = build(...)post定义为调用构建的函数,那么这不是正确的语法。如果您想使用此方法,则必须说post = lambda {build(...)}。这将允许expect方法执行post并检查它引发的错误。

或者,您可以直接传递一个块,例如:

expect{build(...)}.to ...

有关更多示例,请参阅https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/expect-error