2012-08-29 4 views
6

며칠 동안 지금까지는 솔기가 무엇인지 알아 내려고 노력한 결과 매우 쉽게 할 수있었습니다 ... 그러나 난 아직 레일 세계에 새롭지는 않습니다. 루비와 나는이 작업을 할 수 없다 ... :counter_cache 열의 Rspec 테스트 결과는

어쨌든 문제는 내가 수동으로 테스트 할 때 꽤 잘 작동하는 내 모델의 counter_cache 열을 가지고 있다는 것이다. 그러나 나는 TDD 일을하고 싶다. 그리고 나는 알 수없는 어떤 이유로 rspec에서 그들을 시험하기 위해 솔기를 할 수 없다? 어쨌든 여기

내 모델의 예입니다 (사용자 & 미디어 코멘트) : 여기

class User < ActiveRecord::Base 
    has_many :comments 
    has_many :media, dependent: :destroy 
end 

class Comment < ActiveRecord::Base 
    attr_accessible :content, :user_id 
    belongs_to :commentable, polymorphic: true, :counter_cache => true 
    belongs_to :user, :counter_cache => true 

    validates :user_id, :presence => true 
    validates :content, :presence => true, :length => { :maximum => 255 } 
end 

class Medium < ActiveRecord::Base 
attr_accessible :caption, :user_id 

belongs_to :user, :counter_cache => true 

has_many :comments, as: :commentable 

validates :user_id, presence: true 
validates :caption, length: { maximum: 140 }, allow_nil: true, allow_blank: true 

default_scope order: 'media.created_at DESC' 
end 

샘플의 테이블의 스키마 설정의 위치 :

create_table "users", :force => true do |t| 
    t.integer "comments_count",   :default => 0, :null => false 
    t.integer "media_count",   :default => 0, :null => false 
end 

create_table "comments", :force => true do |t| 
    t.text  "content" 
    t.integer "commentable_id" 
    t.string "commentable_type" 
    t.datetime "created_at",  :null => false 
    t.datetime "updated_at",  :null => false 
    t.integer "user_id" 
end 

create_table "media", :force => true do |t| 
    t.integer "user_id" 
    t.string "caption" 
    t.datetime "created_at",     :null => false 
    t.datetime "updated_at",     :null => false 
    t.integer "comments_count", :default => 0, :null => false 
end 

그리고 지금 여기 것은의 샘플입니다 내가 시도한 rspec 예 :

require 'spec_helper' 

describe "Experimental" do 

    describe "counter_cache" do 
    let!(:user) { FactoryGirl.create(:user)} 

    subject { user } 

    before do 
     @media = user.media.create(caption: "Test media") 
    end 

    its "media array should include the media object" do 
     m = user.media 
     m.each do |e| 
     puts e.caption # Outputting "Test media" as expected 
     end 

     user.media.should include(@media) #This works 
    end 

    it "media_count should == 1 " do # This isnt working? 
     puts user.media_count #Outputting 0 
     user.media_count.should == 1 
    end 
    end 
end 

마지막으로 오류 메시지 rspec이 나를주고있다 :

Failures: 

    1) Experimental counter_cache media_count should == 1 
    Failure/Error: user.media_count.should == 1 
     expected: 1 
      got: 0 (using ==) 
    # ./spec/models/experimental_spec.rb:24:in `block (3 levels) in <top (required)>' 

Finished in 0.20934 seconds 
2 examples, 1 failure 

또한 내 모든 모델의 모든 counter_cache 열에 대해 발생합니다. 또한 여러 가지 다른 방법으로이 테스트를 시도했지만 위의 오류 메시지는 모두 반환합니다.

정말 누군가가 나를 도와 줄 수 있기를 바랍니다. :)

미리 감사드립니다. 루크

답변

26

counter_cache은 데이터베이스에서 직접 업데이트되고 있습니다. 나는 내가 이것을 테스트 할 방법을 생각하지 않습니다,

it "media_count should == 1 " do 
    user.reload 
    user.media_count.should == 1 
end 

그러나이 당신이 그것을 다시로드해야 있도록 메모리에로드 한 모델의 사본에 영향을 미치지 않습니다. 테스트를 마치면 테스트가 전혀 필요하지 않은 것처럼 보이는 설치 코드에 테스트가 매우 밀접하게 결합됩니다. 어때요? 이런 식으로 스탠드 얼론 사양으로 어떻습니까?

it "has a counter cache" do 
    user = FactoryGirl.create(:user) 
    expect { 
     user.media.create(caption: "Test media") 
    }.to change { User.last.media_count }.by(1) 
end 
+1

감사합니다. 모델이 메모리에로드되었고 리로드가 필요하다는 것을 알지 못했습니다. –

+0

이제 user.reload 메서드를 사용하여 작업 할 때 작동합니다. 하지만 그때 사양을 정리하고 당신이 제공하는 더 깨끗한 예제를 사용하고 싶었는데, 그리고 이것은 작동하지 않습니까? –

+0

내가 얻는 오류는 다음과 같습니다. –