【问题标题】:Rspec testing of counter_cache column's returning 0counter_cache 列返回 0 的 Rspec 测试
【发布时间】:2012-08-29 04:47:20
【问题描述】:

几天来,我一直在努力寻找应该很容易做到的接缝的底部......但是,我对 Rails 和 ruby​​ 的世界仍然很陌生,我只是无法工作一出... :p

无论如何,我遇到的问题是我的模型中有许多 :counter_cache 列,在手动测试它们时它们都工作得很好。但是,我想做 TDD 的事情,但由于某种未知原因,我无法在 rspec 中测试它们?

无论如何,这里是我的模型(用户、cmets 和媒体)的示例:

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】:

    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
    

    【讨论】:

    • 非常感谢!我不知道模型已加载到内存中,因此需要重新加载。
    • 好的,所以现在使用 user.reload 方法执行此操作。但是我想清理规范并使用您提供的更简洁的示例,这不起作用?
    • 1) 实验数据验证 cmets_count 字段应该有一个计数器缓存失败/错误:期望 { 结果应该已更改为 1,但已更改为 0 # ./spec/models/experimental_spec.rb: 39:in `block (4 levels) in '
    • 抱歉,最后几个 cmets 无效...这一次它实际上是我的代码中的一个错误!耶它的工作!多谢! :)
    • 我知道这已经过时了,而且我可能已经看了很长时间了,现在我错过了一些简单的东西,但是你知道为什么result should have been changed by 1, but was changed by 0 失败了吗?我也一样。我遇到了软删除的情况,我手动处理计数器缓存,需要以类似的方式对其进行测试。
    【解决方案2】:

    对于 testng counter_cache,您可以使用 Shoulda-Matchers gem,开箱即用 method

    【讨论】:

      猜你喜欢
      • 2015-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多