Counter_cache列的Rspec测试返回0

问题描述 投票:7回答:1

几天以来,我一直试图找到应该很容易做到的接缝的底部......但是我仍然对铁轨和红宝石的世界很新,我只是不能解决这个问题。 ..: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的问题。

ruby-on-rails ruby rspec rspec2 counter-cache
1个回答
27
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.