2013-03-11 40 views
0

我的rspec测试都运行正常,除非我复制对象以测试属性的唯一性。测试重复对象时rspec错误[Rails]

这里是模型:

应用程序/模型/ 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的相同错误信息。任何想法发生了什么?

回答

0

发现问题:根本不在我的规格中,而是在模型的before_save块中。我将driver.rb中的行18-23替换为

before_save { self.last_name = last_name.gsub(' ', '-').split('-').each { |x| x.capitalize! }.join('-') } 

并且同样适用于first_name块。现在测试运行良好。更重要的是,这个模型现在实际上正在做我打算做的事情。我想这就是测试的目的!