7

何日もの間、私は継ぎ目の底に到達して、非常に簡単に実行できるようにしようとしてきました...しかし、私はまだレールとルビーの世界に非常に慣れていないので、これを解決することはできません。 ..:p

とにかく、私が抱えている問題は、モデルにいくつかの: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列で発生していることに注意してください。また、これをテストするさまざまな方法を試しましたが、すべて上記のエラーメッセージが返されます。

誰かがこれで私を助けることができることを本当に望んでいます。:)

事前にヒープに感謝します!ルーク

更新:これはcounter_cultureにも同じように影響し、以下の解決策はcounter_cultureの問題も修正します。

4

2 に答える 2

29

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
于 2012-08-29T05:16:52.307 に答える
0

testng counter_cacheには、Shoulda-Matchers gemを使用できますが、すぐに使用できるメソッドがあります。

于 2020-09-09T07:24:33.937 に答える