2012-08-07 53 views
3

试图找出为什么我的rspec测试失败。最值得注意的是似乎矛盾的失败信息。说明我有一个ActiveRecord :: RecordInvalid错误,这正是我声称应该发生的事情。Rails Rspec模型规范用户:email ActiveRecord :: RecordInvalid

这里是我的user.rb

... 
validates_presence_of :email 
... 

这里是我的users_spec.rb

... 
it "is invalid without email" do 
    Factory(:user, email: nil).should raise_error(ActiveRecord::RecordInvalid) 
end 
... 

这里输出:

Failures: 

    1) User a user (in general) is invalid without email 
    Failure/Error: Factory(:user, email: nil).should raise_error(ActiveRecord::RecordInvalid) 
    ActiveRecord::RecordInvalid: 
     Validation failed: Email is invalid, Email can't be blank 
    # ./spec/models/user_spec.rb:34:in `block (3 levels) in <top (required)>' 

本来我是这样的测试,但它保持失败,所以我决定指定我期待的错误。

it "is invalid without email" do 
    Factory(:user, email: nil).should_not be_valid 
end 

回答

8

你的代码是不工作的原因是你想实际测试其有效性之前创建一个无效的模型。你想要做的是建立一个有效的模式,改变的东西,并检查它是无效的,就像这样:

it "is invalid without email" do 
    user = Factory(:user) 
    user.email = nil 
    user.should_not be_valid 
end 

我个人很喜欢来定义我的模型在before块,设置是为subject,然后更改属性中的每个规格和检查的有效性,这样的:

before do 
    @user = FactoryGirl.create(:user) 
end 

subject { @user } 

it "is invalid without email" do 
    subject.email = nil 
    should_not be_valid 
end 

为了记录在案,如果你想测试记录创建引发的错误(这绝对是做到这一点的最好方式) ,你可以通过将Factory呼叫打包在lambda,像这样:

lambda { 
    Factory(:user, :email => nil) 
}.should raise_error(ActiveRecord::RecordInvalid) 
+0

谢谢,这完全有道理。你觉得让(!:user){Factory(:user)}而不是之前做...结束? – botbot 2012-08-07 22:34:57

+0

顺便说一句,为什么你不建议*不*包装在一个lambda {}或期待{}? – botbot 2012-08-07 22:41:24

+0

我的意思是我不会建议通过检查错误提示来检查有效性。使用'lambda'来检查在其他上下文中引发错误是完全正确的。 – 2012-08-07 22:47:40

相关问题