10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RSpecのletでcreateした時に気をつけること 〜遅延評価〜

Posted at
環境
Rails 6.0.0
RSpec 3.9
factory_bot 5.1.1

自分がプチハマりしたので備忘録も兼ねて。

RSpecを書いているとよく見る以下のようなコード。

before do
  @user = create(:user)
end
let(:user) { create(:user) }

この2つはほぼ同じ事をしています。
factoryファイルを元にDBにユーザ情報を作成、前者は@user、後者はuserという変数に代入をします。

ここだけ見ていると、letを使った方が1行で書けるし、letだけ使っていれば問題なさそうな気もします。
しかし注意しなければいけないことがあります。

以下のように、代入した変数を使わずにActive Recordにアクセスする場合、letだとエラーが発生します。

User.find 1

=> ActiveRecord::RecordNotFound: Couldn't find User with 'id'=1

これは、letが遅延評価される(代入した変数が参照されたタイミングで評価される)ために起こります。
User.find user.id ならエラーになりません。

遅延評価されたくない場合はletが使えないのかというと、そういうわけではありません。
遅延評価をしないlet!が用意されています。
let!(:user) { create(:user) } とすれば、テストを行う前(before doと同じタイミング)に実行されます。

遅延評価にも、必要のない時まで処理をしなくてすむといったメリットがありますので、適切な方を選べるようにしたいですね。

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?