Rails - RSpec - 「let」と「let!」の違い 質問する

Rails - RSpec - 「let」と「let!」の違い 質問する

私は、RSpec マニュアル違いについては述べていますが、まだ混乱している点もあります。「The RSpec Book」を含む他のすべての情報源は「let」についてのみ説明しており、「The Rails 3 Way」はマニュアルと同じくらい混乱しています。

「let」は呼び出されたときにのみ評価され、スコープ内で同じ値を保持することを理解しています。したがって、マニュアル最初のテストは、「let」が 1 回だけ呼び出されるため合格し、2 番目のテストは最初のテストの値 (最初のテストで 1 回評価され、値が 1 である) に追加されるため合格します。

それに続いて、「let!」は定義時に評価され、呼び出されたときに再度評価されるため、「count.should eq(1)」ではなく「count.should eq(2)」としてテストが失敗しないはずはありませんか?

ご協力いただければ幸いです。

ベストアンサー1

非常に簡単な例で、letとの違いを理解しました。まずはドキュメントの文章を読んでから、実際に出力を見てみましょう。let!

letについてドクターは言う:-

...let遅延評価: 定義したメソッドが最初に呼び出されるまで評価されません。

以下の例で違いがわかりました:-

$count = 0
describe "let" do
  let(:count) { $count += 1 }

  it "returns 1" do
    expect($count).to eq(1)
  end
end

今すぐ実行してみましょう:-

arup@linux-wzza:~/Ruby> rspec spec/test_spec.rb
F

Failures:

  1) let is not cached across examples
     Failure/Error: expect($count).to eq(1)

       expected: 1
            got: 0

       (compared using ==)
     # ./spec/test_spec.rb:8:in `block (2 levels) in <top (required)>'

Finished in 0.00138 seconds (files took 0.13618 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/test_spec.rb:7 # let is not cached across examples
arup@linux-wzza:~/Ruby>

なぜエラー? なぜなら、ドクターが言ったようにlet定義したメソッドが最初に呼び出されるまで評価されません。の中に、 を呼び出さなかったcountため、は$count依然として0によって増加されません1

さて、その部分ですlet!。ドクターはこう言っています

....各例の前にlet!を使用してメソッドの呼び出しを強制することができます。つまり、ヘルパーメソッドの内部ただし、例が実行される前に呼び出されます。

これもテストしてみましょう:-

変更後のコードはこちら

$count = 0
describe "let!" do
  let!(:count) { $count += 1 }

  it "returns 1" do
    expect($count).to eq(1)
  end
end

このコードを実行してみましょう:-

arup@linux-wzza:~/Ruby> rspec spec/test_spec.rb
.

Finished in 0.00145 seconds (files took 0.13458 seconds to load)
1 example, 0 failures

ご覧のとおり、 は$countを返す1ので、テストに合格しました。これは、例の中ではlet!呼び出していないのに、例の実行前に実行される を使用したために発生しました。count

これが とletlet!違いです。

おすすめ記事