2011-11-23 6 views
4

많은 Likes를 가진 Solutions라는 모델이 Rspec으로 테스트됩니다. 솔루션에는 보유한 Likes 수 (counter_cache)가 저장됩니다. "likes_count"속성 (및 해당 db 필드)이 있습니다.Rails 3 및 Rspec : 카운터 캐시 열이 예상대로 2로 업데이트 됨 1

솔루션에 연결된 Like 레코드를 만들 때 솔루션 속성 "likes_count"를 nil에서 1로 업데이트해야합니다. 콘솔에서이를 수행하면 작동합니다.

그러나 내가 콘솔에서와 같은 일을하고, 스펙을 실행할 때, 그것은 작업 방법 (콘솔) 을 살펴 보자 2.

으로 설정, 두 번 "likes_count"필드를 업데이트 :

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입니다 PEC :

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

답변

2

당신은 당신의 로그에 답을했습니다 :

  • 당신이 be를 사용, 항상 true1 같은 객체의 몇 가지에 대해 동일하다 object_id를 비교합니다. id1 인 것은 2 인 것으로 보입니다. 1.object_id #=> 2

  • 그래서 당신의 시험을 대체 : solution.reload.likes_count.should eql 1를하거나

6

solution.reload.likes_count.should == 1은 저도 같은 문제를 겪고 콘솔보십시오. 내 spec_helper.rb이 두 번째로 모델을로드 중이므로 두 번째 콜백을 만들어 카운터를 업데이트하는 것으로 나타났습니다. 솔루션 모델이 다른 프로세스에 의해 다시로드되지 않는지 확인하십시오.

위의 대답도 맞습니다. be 대신 ==을 사용해야 비교가 가능하지만 로그 파일에 표시되는 여러 업데이트는 수정되지 않습니다.

+0

네, 그게 문제였습니다. 고맙습니다, jkronz! 이 스 니펫은 Spork.each_run 블록에서 문제를 일으키고 있습니다. 'Dir [ "{Rails.root}/app/**/*. rb"]. each {| f | 로드 f}' –

+0

이 동일한 문제가 있지만 두 번로드하는 위치를 찾을 수 없습니다. 이 디버깅하는 방법에 대한 제안? 레일 4.1을 사용하고 있습니다. 감사. –