0

に問題がありcounter_cacheます。3 つのモデルがあるとします。User と Article には多くの ArticleUpvotes があります。ユーザーは記事の ArticleUpvote を作成できます。

ユーザー

# models/user.rb
class User < ActiveRecord::Base
  has_many :upvotes, class_name: 'ArticleUpvote'

  def upvote(article)
    article.upvotes.create(user: self)
  end
end

論文

# models/article.rb
class Article < ActiveRecord::Base
  has_many :upvotes, class_name: 'ArticleUpvote'
end

記事に賛成票を投じる

# models/article_upvote.rb
class ArticleUpvote < ActiveRecord::Base
  include ArticleVote

  belongs_to :article, dependent: :destroy, counter_cache: :upvotes_count
end

# models/concerns/article_vote
module ArticleVote
  extend ActiveSupport::Concern

  included do
    belongs_to :user

    validates :user, presence: true
  end
end 

テストの失敗

context 'voting' do
  let(:user) { FactoryGirl.create(:user) }
  let(:article) { FactoryGirl.create(:article) }

  context '#upvote' do
    it 'adds upvote to article' do
      user.upvote(article)
      expect(article.upvotes.size).to eq 1
    end
  end
end

エラー

1) User voting #upvote adds upvote to article
 Failure/Error: expect(article.upvotes.size).to eq 1

   expected: 1
        got: 0

   (compared using ==)

テストに合格する

テストボディを次のように変更するだけです:

user.upvote(article)
article.upvotes.size # Added this line compared to failing version
expect(article.upvotes.size).to eq 1

またはこれを行う:

expect{ user.upvote(article) }.to change{ article.upvotes.size }.by 1

テストに合格します。なぜこうなった?

4

1 に答える 1

1

例を次のように変更します。

it 'adds upvote to article' do
  user.upvote(article)
  expect(article.reload.upvotes.size).to eq 1
end

与えられた例が失敗した理由は、spec がusingarticleによって作成されたオブジェクトを保持していたため、データベースに変更が加えられたことを認識していないためです。変更が反映されるように記事を作成する必要があります。FactoryGirlFactoryGirl.create(:article)reload

他の合格テストでは、すなわち、

expect{ user.upvote(article) }.to change{ article.upvotes.size }.by 1 

メソッドが原因で暗黙的なリロードが発生するため、例は合格ですchange

于 2014-04-04T21:13:53.687 に答える