letの遅延評価でつまづいたので、メモしておく。
letとは
RSpecのドキュメントより
letはメモ化のためのヘルパーメソッド(memoized helper method)を定義するために使います。
値はキャッシュされ、同じexampleの中では何度呼ばれても同じ値(同じオブジェクト)が返ります。
しかし、exampleが異なる場合は異なるオブジェクトが返ります。
letで定義された変数は最初に参照された時に値をキャッシュする。
遅延評価でつまずくこと
例えば以下のリレーションの場合。
class user
has_many :articles
end
class article
belong_to :user
end
以下テストコードを書くと、articleのデータがDBに保存されていないため、エラーとなる。
let(:user){ FactoryGirl.create(:user)}
let(:article){ FactoryGirl.create(:article, :user_id => user.id, :title => 'letの遅延評価')}
it 'test' do
expect(user.articles.first.title).to eq 'letの遅延評価'
end
解決策
let(:article)
をlet!(:article)
に変更すれば、事前にarticleをcreateしてくれるので解決する。
(userはuser.id
が参照されたタイミングでcreateされる。なのでlet(:user)
のままで構わない。)
let(:user){ FactoryGirl.create(:user)}
let!(:article){ FactoryGirl.create(:article, :user_id => user.id, :title => 'letの遅延評価')}
it 'test' do
expect(user.articles.first.title).to eq 'letの遅延評価'
end
参考