Techioz Blog

let で定義された変数をリロードする方法

概要

ユーザーには多くのコメントがあるため、コメントが関連付けられたファクトリー ユーザー (user_with_comment) を用意したいと思います。

factory :user, class: User  do |t|
  ...
  factory :user_with_comment do |t|
    after(:create) do |user|
      FactoryGirl.create(:comment, user_id: user.id)
    end
end

正常に動作します… FactoryGirl.create(:user_with_comment) を呼び出すと、テスト データベースにユーザーと関連コメントが作成されます。

ただし、controller_spec でいくつかの問題に直面しています。

let を使用すると、コメントを表示するにはユーザーをリロードする必要があります。

let(:user) { FactoryGirl.create(:user_with_comment) }
user.comments.size #=>0
user.reload
user.comments.size #=>1

1 つの解決策は before(:each) を使用することですが、各テストの前に venda とコメントを作成します。

before(:each) do
  @user = FactoryGirl.create(:user_with_comment)
end
@user.comments.size #=>1

または、各テストの前にユーザーをリロードすることもできますが、データベースにもヒットします。

let(:user) { FactoryGirl.create(:user_with_comment) }
before(:each) do
  user.reload
end

この状況での最善のアプローチは何でしょうか?

解決策

let変数をリロードする方法に関する別の問題を検索しているときにこれを目にしていますが、ここで考えられる解決策は、after_createを実行する代わりにファクトリに関連付け自体を使用させることだと思います(質問があったときにそれが利用可能だったかどうかはわかりません)と聞かれましたが):

factory :user, class: User  do |t|
  ...
  factory :user_with_comment do
    # might need create(:comment) but in my testing build worked
    comments { [build(:comment)] }
  end
end
let(:user) { FactoryGirl.create(:user_with_comment) }
user.comments.size #=> 1