2013-04-23 42 views
2

在一个简单的rails应用程序与企业模型轨,RSpec的,早该validate_presence_of失败,二传手叫了两声

class Company < ActiveRecord::Base 

    # Attributes 
    attr_accessible :name 

    validates_presence_of :name 

    def name=(s) 
    self[:name] = s.upcase 
    end 
end 

当以下规范文件运行。它失败。

require 'spec_helper' 

describe Company do 

    before :each do 
    @company = Company.new({name: 'my_company'}) 
    end 

    it "should validate presence of name" do 
    @company.should validate_presence_of(:name) 
    end 

end 

调试表明,名字=(一个或多个)方法被调用两次,一次以“my_company”次,用零。

我不明白为什么第二次电话会与nill发生。 这里使用的宝石:

gem 'rails', '3.2.13' 
gem 'mysql2' 

group :development, :test do 
    gem 'rspec-rails', '2.11.0' 
    gem 'shoulda-matchers', :require => false 
end 

回答

1
  • 早该旨在被用来写一个衬里规格{应当validate_presence_of(:名称)}
    它{should validate_presence_of(:name).with_message(/ is not optional /)}

    所以你可以用更易读的方式编写你的规格如下:

    describe 'validations' do 
    it {should validate_presence_of(:name)} 
    end
  • 关于你提到的两个赋值为name字段的问题:

    1. 的第一项任务是在规范的完成前(:每个)块和
    2. 早该存在验证尝试分配零值对于您指定的所有属性进行验证的,其中您的型号为:名称
      您的重写名称=方法发生在这个零值,并且它引发一个错误,因为它不能提升nil。上面显示的一个班轮规格也会由于相同的原因而失败。要解决这个问题,你可以改变你的setter方法做s.try(:upcase)。所以它可以在零值上工作并且不会引起任何问题。
+0

关于你的2.你从哪里得到这些信息?“应该出现验证器试图为所有属性分配零值”。我仍然不明白为什么该方法被调用两次。第一个调用名称作为一个值,第二个调用它为null。 – Alpha 2013-04-24 03:34:24

+0

@alpha,我经历了shoulda ** validate_presence_of_matcher **的代码。有一个方法**匹配**,它在内部调用** disallows_value_of(blank_value,@expected_message)**。如果你遵循这个代码,你会看到在**匹配中没有值的任务** ** AllowValueMatcher的方法 – rajashree 2013-04-24 05:22:26

0

其原因可能是你在新的name方法提到name

更好地使用write_attribute方法作为您提到的文档。

要读取它为:如文档中提到的一样

def name=(s) 
    write_attribute(:name, s.upcase) 
end 
+0

第二种方法name =修改name的值,所以我需要它。什么应该是正确的方式?并没有解释为什么第二个调用有一个nill值参数 – Alpha 2013-04-23 17:41:49

+0

@Alpha,是的,我知道你需要它,但是你不需要写def,因为'attr_accessible:name'已经为你生成了这个方法自动。删除该def,你的代码将工作。 – 2013-04-23 17:43:33

+0

@ Alpha,检查我的更新。 – 2013-04-23 17:48:18