开发者

Rspec, shoulda, validate_uniqueness_of with scope and wrong error message

I have following Rspec test:

describe Productlimit do

  before(:each) do 
    @productlimit = Factory.create(:productlimit, :user => Factory.create(:user))
  end

  subject { @productlimit }

  ...

  it { should validate_uniqueness_of(:price_cents).scoped_to(:direction_down, :currency, :market_id, :user_id) }
  ...
end

But I get following confusing error:

1) Productlimit 
     Failure/Error: it { should validate_uniqueness_of(:price_cents).scoped_to(:direction_down, :currency, :market_id, :user_id) }
       Expected errors to include "has already been taken" when price_cents is set to 9530, got errors: ["direction_down has already been taken (false)"]

Can you help me? I don't understand why this isn't working, because the error message seems to be correct?

EDIT:

This happens too in other situations as well:

# product_spec.rb
...
it { should validate_numericality_of(:price).with_message("price_cents must be greater than 0 (0)") }  

# rake spec:models
Failure/Error: it { should validate_numericality_of(:price).with_message("price_cents must be greater than 0 (0)") }
   Expected e开发者_StackOverflow中文版rrors to include "price_cents must be greater than 0 (0)" when price is set to "abcd", got errors: ["price_cents must be greater than 0 (0)"]


To check validate_uniqueness_of(:field) but for this you should at lease one record in database to check uniquness constrain. Here is....

before do
  @country = FactoryGirl.create(:country, :id =>"a0000007-0000-0000-0000-000000000009",:currency_id => "a0000006-0000-0000-0000-000000000004",:merchant_id => "a0000001-0000-0000-0000-000000000002",:country_code => 'CAN', :name => 'Canada')
end

To validate uniqueness

it { should validate_uniqueness_of(:country_code)}

It will work out try it out.


To add to what Riche has said about uniqueness validation on :direction_down, I would suspect the way your ProductLimit factory generates values for :direction_down. It might not always be generating unique values for all attributes which have the uniqueness validation on them.

Also, one issue I have faced with uniqueness validation is the first object ( the subject in your case) thats is created before the validation check should not have any conflicting values with ones the factory "randomly" generates. To illustrate with a trivial example,

Factory(:product_limit, :direction_down => "abc")
it { should validate_uniqueness_of(:price_cents).scoped_to(:direction_down) }

has the potential to fail wrongly, in case the object constructed by the shoulda matcher ends with direction_down set to "abc" when there is a uniqueness validation on :direction_down.


Do you have the database_cleaner settings in the sepc_helper? if not then add

gem "database_cleaner"

in spec_helper.rb add the following in the RSpec.configure block

 config.use_transactional_fixtures = false

 config.before(:suite) do
   DatabaseCleaner.strategy = :truncation
 end

 config.before(:each) do
   DatabaseCleaner.start
 end

 config.after(:each) do
   DatabaseCleaner.clean
 end

Also can you post the Factory code? just to have a clearer picture.

I hope this helps.

Also check if there is any uniqueness validation on :direction_down attribute.


Try to remove test/fixtures/* and try to manually create object before testing uniqueness (not using Factory). Also, have you tried:

    class MyModelTest < ActiveSupport::TestCase 


The error isn't correct for the matcher because it's complaining about the uniqueness of :direction_down when you asked it to test that the uniqueness of :price_cents was valid.

Does the code for your model include a validates_uniqueness_of :direction_down? If so, that would explain the message.


The first case (with validate_uniquess_of) happened to me after an unexpected crash. A simple rake db:test:prepare fixed it.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜