开发者

Rails 3: Duplicate validation error messages during testing

I'm getting some weird validation behavior: it's duplicating my validation error messages and I can't figure out what's causing it... it doesn't do this in the rails console.

Here is the validation from my Phone model:

# phone.rb
validates :number, :length => { :minimum => 3 }

My spec:

开发者_Go百科require 'spec_helper'

describe Phone do
  it "requires a number" do
    user = User.make!
    @p = Phone.new(number:nil,user_id:user.id,type:2)
    @p.valid?
    puts @p.errors.inspect 
    @p.should have(1).error_on(:number)
  end

My test results:

# rspec and machinist
#<ActiveModel::Errors:0x000000036f1258 @base=#<Phone id: nil, user_id: 614, kind: nil, number: nil, created_at: nil, updated_at: nil>, @messages={:number=>["is too short (minimum is 3 characters)", "is too short (minimum is 3 characters)"]}>
F

Failures:

  1) Phone requires a number
     Failure/Error: @p.should have(1).error_on(:number)
       expected 1 error on :number, got 2
     # ./spec/models/phone_spec.rb:11:in `block (2 levels) in <top (required)>'

Finished in 0.50988 seconds
1 example, 1 failure

As you can see, I'm getting "is too short (minimum is 3 characters)" twice... It's also /only/ happening during testing. Any ideas?

Thanks!


The problem is in the line:

Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }

in the spec_helper.rb file, in the Spork.each_run block

If you change the method 'load' to 'require', it fixes the problem.

Or if you have a recent enough version of Spork, you can remove the line altogether. I am pretty sure the error is caused when someone is installing a newer version Spork(0.9.0+) with old instructions, because the line:

Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }

doesn't even has to be stated explicitly in the spec_helper.rb file anymore. If it is then when the load method is used in the spec_helper.rb file, it reloads the files specified , most likely the cause of the strange RSpec duplicate validations errors.


I encountered a similar issue of duplicate error messages, but it seemed to stem from my use of a different directory structure than the standard, e.g.:

- app
  \- models_one
  |- models_two
  |- models_three

My load/require call in the Spork.each_run block looked like this:

Dir["#{Rails.root}/app/models_*/*.rb"].each { |f| load f }

I removed this and replaced it with these:

ActiveSupport::Dependencies.clear
ActiveRecord::Base.instantiate_observers

And there were no more duplicate error messages.

I was helped by this post: http://adams.co.tt/blog/2012/04/12/duplicate-active-model-validation-errors/ in which the author says it's a 1.8.7-specific problem which involves requiring different paths which resolve to the same file, but I am using 1.9.3 so it may not be related.


I'm not sure if this is going to solve your problem, but rspec is very quirky if you don't follow rspec convention. Try some more idiomatic rspec like the following:

require 'spec_helper'

describe Phone do
  context :validations do
    let(:user) { double(:user) }
    subject { Phone.new(number:nil,user_id:user.id,type:2) }

    before do
      subject.valid?
    end

    it 'should have a minimum length of 3' do
      subject.should have(1).error_on(:number)
    end
  end
end

I'd also like to suggest that you shouldn't unit test Rails' built in validations; they are already tested in Rails itself. Specifically, your length validation is tested in activemodel/test/cases/validations/length_validation_test.rb. The behavior of the validations should be covered in your integration tests.

I hope that's helpful.


I'm having the same problem (using rspec & spork).

I suspect it's something to do with the model being required twice, causing validations to run twice.

If you explicity require 'phone' at the top of your spec, it seems to fix it.

But I'd really like to know what's causing the problem...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜