Rspec,shoulda,validate_uniqueness_of,带有范围和错误的错误消息

时间:2011-07-03 16:35:31

标签: ruby-on-rails ruby-on-rails-3 validation rspec shoulda

我遵循了Rspec测试:

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

但是我遇到了令人困惑的错误:

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)"]
你能帮帮我吗?我不明白为什么这不起作用,因为错误信息似乎是正确的?

修改

在其他情况下也会发生这种情况:

# 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 errors 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)"]

6 个答案:

答案 0 :(得分:11)

要检查validate_uniqueness_of(:field),但为此,您应该在数据库中至少有一条记录来检查uniquness约束。 这是....

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

验证唯一性

it { should validate_uniqueness_of(:country_code)}

可以试一试。

答案 1 :(得分:3)

要在{direction_down上添加Riche关于唯一性验证的内容,我会怀疑ProductLimit工厂为:direction_down生成值的方式。它可能并不总是为所有具有唯一性验证的属性生成唯一值。

此外,我遇到的唯一性验证的一个问题是第一个对象(在您的情况下是主题),它是在验证检查不应与工厂“随机”生成的值之间产生任何冲突值之前创建的。用一个简单的例子说明,

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

有可能失败错误,以防在由于:direction_down存在唯一性验证时,由shoulda匹配器构造的对象以direction_down设置为“abc”结束。

答案 2 :(得分:2)

你在sepc_helper中有database_cleaner设置吗? 如果没有,那么添加

gem "database_cleaner"

在spec_helper.rb中 在 RSpec.configure

中添加以下内容
 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

您也可以发布工厂代码吗?只是为了有一个更清晰的画面。

我希望这会有所帮助。

同时检查是否有任何唯一性验证:direction_down属性。

答案 3 :(得分:0)

尝试删除test/fixtures/*并尝试在测试唯一性之前手动创建对象(不使用Factory)。还有,你试过了吗?

    class MyModelTest < ActiveSupport::TestCase 

答案 4 :(得分:0)

匹配器的错误不正确,因为当你要求它测试它的唯一性时,它会抱怨:direction_down的唯一性:price_cents是有效的。

您模型的代码是否包含validates_uniqueness_of :direction_down?如果是这样,那将解释该消息。

答案 5 :(得分:0)

第一个案例(validate_uniquess_of)在意外崩溃后发生在我身上。一个简单的rake db:test:prepare修复了它。