4

我正在使用 Rspec 测试一个名为 Solutions 的模型,它有很多喜欢。解决方案存储它有多少喜欢(counter_cache)。它有一个“likes_count”属性(和相应的数据库字段)。

当我创建与解决方案关联的 Like 记录时,我希望解决方案属性“likes_count”应该从 nil 更新为 1。当我在控制台中执行此操作时,它可以工作。

但是当我运行规范时,在控制台中做同样的事情时,它会更新两次“likes_count”字段,将其设置为 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

看看规范结果不工作

 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 查询在测试中被调用了两次。

  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正在第二次加载模型,因此创建了第二个回调来更新计数器。确保您的解决方案模型没有被其他进程重新加载。

上面的答案也是正确的:您需要使用==而不是进行be比较,但这不会修复您在日志文件中看到的多个更新。

于 2011-11-29T01:38:19.013 回答
2

您的日志中有答案:

  • 当您使用be时,它会比较和object_id等几个对象始终相同的。的似乎是。在控制台中尝试:true1id121.object_id #=> 2

  • 因此,将您的测试替换为:solution.reload.likes_count.should eql 1甚至solution.reload.likes_count.should == 1

于 2011-11-23T20:11:37.107 回答