2011-07-03 36 views
15

我有以下Rspec的測試:Rspec的,早該,validate_uniqueness_of與範圍和錯誤的錯誤消息

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)"] 
+0

你正在使用什麼版本的shoulda/rspec? – nathanvda

+0

我有shoulda-matchers(1.0.0.beta2),但我用當前的'shoulda'寶石試了一下。 – Lichtamberg

+0

在我看來,你正在測試rails應該已經測試過的東西。如果你的模型中有validate_numericality,爲什麼還要在你的測試中調用它?這是不必要的重複 – corroded

回答

11

要檢查validate_uniqueness_of(:field),但爲此,您應該至少在數據庫中記錄一條記錄以檢查唯一性約束。 這裏是....

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)} 

這將制定出試試。

+0

謝謝你,很棒的提示! –

0

嘗試刪除test/fixtures/*並嘗試(不使用廠)測試的獨特之前,需要手動創建對象。另外,你有沒有嘗試過:

class MyModelTest < ActiveSupport::TestCase 
+0

我測試rspec(根本沒有測試文件夾),並試圖手動保存我的對象,這是可行的。但測試不起作用。 – Lichtamberg

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屬性。

+0

感謝您的回答,ich現在刪除了這個特定的測試並手動測試它...試過了您的解決方案,但也沒有工作.. – Lichtamberg

0

匹配器的錯誤是不正確的,因爲它要求它測試price_cents的唯一性是否有效時,它抱怨direction_down的唯一性。

您的模型的代碼是否包含validates_uniqueness_of :direction_down?如果是這樣,那將解釋消息。

3

要增加Riche關於唯一性驗證的說明:direction_down,我會懷疑ProductLimit工廠爲direction_down生成值的方式。它可能並不總是爲所有具有唯一性驗證屬性生成唯一值。

此外,我唯一遇到的唯一性驗證問題是在驗證檢查之前創建的第一個對象(您的案例中的主題)應該不會與工廠「隨機」生成的任何衝突值創建。用一個簡單的例子說明,

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

具有失敗的潛在錯誤,在情況下,由早該匹配器構造的對象與direction_down組結束於「ABC」時,有一個唯一性驗證:direction_down。

0

第一種情況(與validate_uniquess_of)發生在我意外的崩潰後。一個簡單的rake db:test:prepare修復它。