2011-11-23 63 views
4

我正在測試與Rspec一個名爲解決方案,它有很多喜歡的模型。解決方案存儲多少喜歡(counter_cache)。它有一個「likes_count」屬性(和相應的db字段)。Rails 3和Rspec:計數器緩存列正在更新到2預期1

當我創建一個與解決方案關聯的Like記錄時,我期望解決方案屬性「likes_count」應該從零更新爲1.當我在控制檯中這樣做時,它可以工作。

但是當我運行規範,做同樣的事情我在控制檯做,它更新兩次「likes_count」字段,將其設置爲2

看看(控制檯)WORKING

irb(main):001:0> solution = Factory(:solution) 
irb(main):004:0> solution.likes_count 
=> nil 
irb(main):006:0> like = Factory(:like, :likeable => solution) 
=> #<Like id: 1, user_id: 2, likeable_id: 1, likeable_type: "Solution", 
    created_at: "2011-11-23 19:31:23", updated_at: "2011-11-23 19:31:23"> 
irb(main):007:0> solution.reload.likes_count 
=> 1 

看一看規範結果不工作

1) Solution counter cache should be increased when a like is created 
Failure/Error: subject.reload.likes_count.should be 1 

    expected #<Fixnum:3> => 1 
     got #<Fixnum:5> => 2 

    Compared using equal?, which compares object identity, 
    but expected and actual are not the same object. Use 
    'actual.should == expected' if you don't care about 
    object identity in this example. 
# ./spec/models/solution_spec.rb:45:in `block (3 levels) in <top (required)>' 

這裏是在S佩奇:

describe "counter cache" do 
    let(:solution) { Factory(:solution) } 

    it "should be increased when a like is created" do 
    Factory(:like, :likeable => solution) 
    solution.reload.likes_count.should be 1 
    end 
end 

我看了看test.log中,我意識到,更新該計數器緩存列的數據庫查詢在測試中調用兩次。

SQL (0.5ms) INSERT INTO "likes" ("created_at", "likeable_id", "likeable_type", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?) [["created_at", Wed, 23 Nov 2011 19:38:31 UTC +00:00], ["likeable_id", 121], ["likeable_type", "Solution"], ["updated_at", Wed, 23 Nov 2011 19:38:31 UTC +00:00], ["user_id", 204]] 
    SQL (0.3ms) UPDATE "solutions" SET "likes_count" = COALESCE("likes_count", 0) + 1 WHERE "solutions"."id" IN (SELECT "solutions"."id" FROM "solutions" WHERE "solutions"."id" = 121 ORDER BY id DESC) 
    SQL (0.1ms) UPDATE "solutions" SET "likes_count" = COALESCE("likes_count", 0) + 1 WHERE "solutions"."id" IN (SELECT "solutions"."id" FROM "solutions" WHERE "solutions"."id" = 121 ORDER BY id DESC) 
    Solution Load (0.3ms) SELECT "solutions".* FROM "solutions" WHERE "solutions"."id" = ? LIMIT 1 [["id", 121]] 

回答

2

您已在日誌中的答案:

  • 當您使用be,它比較object_id這始終是像true1一個連接對象相同。 1id似乎是2。嘗試在控制檯:1.object_id #=> 2

  • 因此,與更換您的測試:solution.reload.likes_count.should eql 1甚至solution.reload.likes_count.should == 1

6

我有同樣的問題。事實證明,我的spec_helper.rb第二次加載模型,因此創建第二個回調來更新計數器。確保您的解決方案模型沒有被其他進程重新加載。

上面的答案也是正確的:您需要使用==而不是be來進行比較,但這不會修復您在日誌文件中看到的多個更新。

+0

是的,這是問題所在。非常感謝,jkronz! 這段代碼導致Spork.each_run塊上的問題: 'Dir [「#{Rails.root}/app/**/*。rb」]。{| f |加載f}' –

+0

我有這個相同的問題,但我找不到它加載兩次。有關如何調試的建議?我正在使用rails 4.1。謝謝。 –