2012-08-29 15 views
6

Günler boyunca, dikişin en kolay yapılması gereken bir şey olmanın altını çizmeye çalışıyorum ... Ancak yine de raylar dünyası için çok yeni ve Ruby ve ben sadece bu işe yaramaz ...: pCounter_cache sütununun Rspec testi geri dönüyor 0

Her halükarda, sahip olduğum problem, modelimde birkaç tane: counter_cache sütunları var, bunların hepsi manuel olarak test edilirken oldukça iyi çalışıyor. Ancak ben TDD şey yapmak istiyorum ve bazı bilinmeyen bir nedenle rspec onları test etmek için dikiş olamaz? Neyse burada

modelim en örneğidir (Kullanım & Medya yorumlar gibi): Burada

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 

örnek en tablonun şema kurulumunun şunlardır:

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 

Ve şimdi buradan bir örneğidir Ben denedim bir RSpec örnek:

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 

Ve nihayet hata mesajları sadece RSpec bana veriyor e:

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 

Ayrıca, bu benim modeli en tüm benim counter_cache sütun için oluyor unutmayınız. Bunu test etmenin bir kaç farklı yolunu denedim, ancak hepsi yukarıdaki hata mesajını döndürüyorlar.

Birisi bana bununla yardımcı olabilir umut ediyor. :)

Önceden teşekkürler! Luke

cevap

26

counter_cache doğrudan veritabanında güncellenmektedir. Bunu ben bunu test nasıl olduğunu düşünmüyorum,

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

Ama: Böyle mi yeniden yüklemeniz gerekir böylece belleğe yüklediğiniz modelin kopyasını etkilemeyecektir. Elinizde olduğu gibi, testiniz, orada olması gerekmediği gibi görünen kurulum koduna çok sıkı bir şekilde bağlıdır. Tek başına bir özellik için böyle bir şeye ne dersiniz:

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

Teşekkürler yığınlar! Modelin belleğe yüklendiğini ve yeniden yüklemenin gerekli olduğunu biliyordum. –

+0

tamam, şimdi user.reload yöntemi ile bunu yaparken. Ama daha sonra, spesifikasyonları temizlemeyi ve sağladığınız temizleyici örneğini kullanmayı istedim ve bu işe yaramıyor mu? –

+0

Aldığım hata şudur: –