测试重复对象时的rspec错误[Rails]

时间:2013-03-11 10:35:26

标签: ruby-on-rails-3.2 rspec-rails

我的rspec测试都运行正常,除非我复制对象以测试属性的唯一性。

以下是模型:

的应用程序/模型/ driver.rb

1.  class Driver < ActiveRecord::Base
2.    attr_accessible :last_name, :first_name, :short_name
# irrelevant code
18. before_save do
19.   last_name = last_name.gsub(' ', '-').capitalize!
20.   if last_name.include? '-'
21.     last_name[(last_name.index('-'))+1] = last_name[(last_name.index('-'))+1].capitalize!
22.   end
23. end
24. before_save do
25.   first_name = first_name.gsub(' ', '-').capitalize!
26.   if first_name.include? '-'
27.     first_name[(first_name.index('-'))+1] = first_name[(first_name.index('-'))+1].capitalize!
28.   end
29. end
30. before_save { short_name.downcase! }
# more irrelevant code
59. validates :short_name, presence: true, length: { maximum: 10 },
60.                   uniqueness: { case_sensitive: false }

所以我通过复制驱动程序对象来测试short_name属性的唯一性,如下所示:

规格/模型/ driver_spec.rb

require 'spec_helper'

  describe Driver do

    before do
      @driver = Driver.new(last_name: "Driver", first_name: "Example", short_name: "exdrvr")
    end

  subject { @driver }

  it { should respond_to(:last_name) }
  it { should respond_to(:first_name) }
  it { should respond_to(:short_name) }

  it { should be_valid }

  # a bunch of other tests, all of which work fine

  describe "when short name is already taken" do
    before do
      driver_with_same_short_name = @driver.dup
      driver_with_same_short_name.short_name = @driver.short_name.upcase
      driver_with_same_short_name.save
    end
    it { should_not be_valid }
  end

这是我运行所有测试时得到的结果:

.................................F....

Failures:

  1) Driver when short name is already taken 
     Failure/Error: driver_with_same_short_name.save
     NoMethodError:
       undefined method `gsub' for nil:NilClass
     # ./app/models/driver.rb:19:in `block in <class:Driver>'
     # ./spec/models/driver_spec.rb:128:in `block (3 levels) in <top (required)>'

Finished in 1.74 seconds
38 examples, 1 failure

Failed examples:

rspec ./spec/models/driver_spec.rb:130 # Driver when short name is already taken

因此,除非我复制驱动程序对象,否则基本上所有测试都运行良好。然后last_name属性突然为零。我尝试从模型文件中的第18-23行注释掉before_save块,当然我只是得到了first_name的相同错误消息。知道发生了什么事吗?

1 个答案:

答案 0 :(得分:0)

发现问题:根本不在我的规范中,而是在模型的before_save块中。我用

替换了driver.rb中的第18-23行
before_save { self.last_name = last_name.gsub(' ', '-').split('-').each { |x| x.capitalize! }.join('-') }

同样适用于first_name块。现在测试运行良好。更重要的是,该模型现在实际上正在按照我的意图去做。我猜这就是测试的目的!