2

在带有公司模型的简单 Rails 应用程序中

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

调试显示 name=(s) 方法被调用了两次,一次使用 'my_company',一次使用 nil。

我不明白为什么第二个电话会发生 nill。以下是使用的宝石:

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

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

2 回答 2

1
  • shoulda 旨在用于编写文档中提到的一个班轮规格,例如
    它 { should validate_presence_of(:name)}
    it { should validate_presence_of(:name).with_message(/is not optional/) }

    因此,您可以以更具可读性的方式编写规范,如下所示:

    描述“验证”做  
     它{应该 validate_presence_of(:name)}  
     结尾
  • 关于您对 name 字段的两个分配的问题:

    1. 第一个分配是在您的规范的 before(:each) 块中完成的,并且
    2. 应该存在验证器尝试为您指定要验证存在的所有属性分配 nil 值,如果您的模型是:name
      您覆盖的 name= 方法发生在这个 nil 值上,它会引发错误,因为它不能大写 nil。出于同样的原因,上面显示的一种衬里规格也会失败。要解决此问题,您可以将 setter 方法更改为s.try(:upcase)。所以它可以在 nil 值上工作并且不会引起任何问题。
于 2013-04-23T20:33:21.423 回答
0

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

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

将其解读为:

 def name=(s)
   write_attribute(:name, s.upcase)
 end
于 2013-04-23T17:38:42.660 回答