2011-07-20 73 views
4

我正在尝试为用户模型创建一个测试用例。基本上,它会验证first_name和last_name是否存在。Rails 3.1 Rspec为模型创建测试用例验证字段

我想要做的是检查特定字段上的错误是否为空,它应该是空的。但它总是失败。

这样做的正确方法是什么?

这里是我的代码

在我user_spec.rb

require 'spec_helper' 

describe User do 

    before do 
    @user = User.new 
    end 

    it "must have a first name" do 
    @user.errors[:first_name].should_not be_empty 
    end 

    it "must have a last name" do 
    @user.errors[:last_name].should_not be_empty 
    end 
end 

在我user.rb文件

class User < ActiveRecord::Base 
    validates :first_name, :presence => true 
    validates :last_name, :presence => true 
end 

回答

16

RSpec的支持的 “隐性” 主题的概念。如果您对“describe”块的第一个参数是一个类,RSpec会自动将该类的一个实例用于您的规格。请参阅http://relishapp.com/rspec/rspec-core/v/2-6/dir/subject/implicit-subject

require 'spec_helper' 

describe User do 

    it "must have a first name" do  
    subject.should have(1).error_on(:first_name) 
    end 

    it "must have a last name" do 
    subject.should have(1).error_on(:last_name) 
    end 
end 

导致RSpec的输出(如果使用--format文档)的:

require 'spec_helper' 

describe User do 
    it { should have(1).error_on(:first_name) } 
    it { should have(1).error_on(:last_name) } 
end 

User 
    must have a first name 
    must have a last name 

可以更进一步,如果你是内容与RSpec的输出默认它缩写

导致:

User 
    should have 1 error on :first_name 
    should have 1 error on :last_name 
18

你可以通过简单地做这个问题,以及测试:

describe 'validations' do 
    it { should validate_presence_of :firstname } 
    it { should validate_presence_of :lastname } 
end 

看看在shoulda matchers对于所有此类标准的Rails验证。 这种方式不仅更简洁,而且照顾正面的情况。这意味着你不需要测试下面提到的场景:

it "passed validations when first_name is set" 
    user = User.create(:firstname => 'f', :lastname => 'l') 
    user.errors[:first_name].should be_empty 
    user.errors[:last_name].should be_empty 
end 
+2

Upvoted for future viewingers。应用程序匹配器对测试验证更优雅。 – MikeH

+1

而不是使用'it“来描述应该...”do“最好使用'it {should validate_presence_of:firstname}' – morgents

+0

我根据@moregeek提出的新的更好的语法更新了答案 – jake