4

私はRspecを使って、多くのLikeを持つSolutionsという名前のモデルをテストしています。ソリューションは、いいねの数を保存します (counter_cache)。「likes_count」属性 (およびそれぞれの db フィールド) があります。

ソリューションに関連付けられた Like レコードを作成するとき、ソリューション属性 "likes_count" を nil から 1 に更新する必要があることを期待しています。コンソールでそれを行うと、機能します。

しかし、仕様を実行すると、コンソールで行うのと同じことを実行すると、「likes_count」フィールドが 2 回更新され、2 に設定されます。

(コンソールで)見てみましょ

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

仕様の結果を見てくださいNOT WORKING :

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

仕様は次のとおりです。

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 を確認したところ、カウンタ キャッシュ列を更新する db クエリがテストで 2 回呼び出されていることがわかりました。

  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]]
4

2 に答える 2

6

私も同じ問題を抱えていました。spec_helper.rbモデルを 2 回読み込んでいたため、カウンターを更新するための 2 回目のコールバックが作成されたことが判明しました。ソリューション モデルが別のプロセスによって再ロードされていないことを確認してください。

上記の答えも正しいです。比較を行う==代わりに使用する必要がありbeますが、ログ ファイルに表示される複数の更新は修正されません。

于 2011-11-29T01:38:19.013 に答える
2

ログに答えがあります:

  • を使用すると、とのようないくつかのオブジェクトに対して常に同じである がbe比較されます。のは のようです。コンソールで試してください:object_idtrue1id121.object_id #=> 2

  • したがって、テストを次のように置き換えます:solution.reload.likes_count.should eql 1またはsolution.reload.likes_count.should == 1

于 2011-11-23T20:11:37.107 に答える