0
0

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 3 years have passed since last update.

letとlet!とbeforeの使い分け

Posted at

こんにちは、プレイライフの熊崎です。
最近野菜をとれていなかったので、この土日はいっぱい野菜を食べたいと思います。

本日3本目はletとbeforeの使い分けについてアウトプットしていきます。

let

メモ化されたヘルパーメソッドを定義する。同じexampleの中ではキャッシュされるが、異なるexample間ではキャッシュされない。
遅延評価される。letが定義するメソッドが最初に呼び出されるまで評価されない。

sample_spec.rb
let(:user) { User.create(name: "田中太郎") }

# letは遅延評価されるため、userが呼び出されるまで、Userにはレコードが作られていない状態になる。そのためテストが通らない。
it 'ユーザーが取得できること' do
  expect(User.find_by(name: "田中太郎")).to eq user
end

let!

各exampleの実行前に、定義されたメソッドを呼び出すことができる。

sample_spec.rb
let!(:user) { User.create(name: "田中太郎") }

# let!にすることで、以下のテストケースの前に、userメソッドが呼ばれるため、Userにレコードが存在する状態になる。そのため、テストには通る。
it 'ユーザーが取得できること' do
  expect(User.find_by(name: "田中太郎")).to eq user
end

before

テストケースの前に、行いたい処理をブロック内に書くことで、テストケースが実行される前にブロック内の処理が行われるようにする。

sample_spec.rb
before do
  User.create(name: "田中太郎")
end

# この場合はuserがテストコードにないので、let(:user)を使用する必要がない。
it 'ユーザーが取得できること' do
  expect(User.count).to eq 1
end

それぞれの使い分け

先ほどまでの実例から、以下のように使い分けるのが適切だと感じた。

let:テストコード内に、定義したヘルパーメソッドが存在する場合

let!:テストコード内に、定義したヘルパーメソッドが存在し、かつテストの実行前にヘルパーメソッドを実行したい場合

before:テストコード内でヘルパーメソッドを定義する必要がない場合

最後に

それぞれの挙動を理解していないと、テストコードに存在しないヘルパーメソッドをletで用意している。といった状況になり、レビュワーや数ヶ月後の自分が混乱するので使い分けを徹底していく必要があると感じた。

参考記事

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?