[解決済み] RSpec: letとbeforeブロックの違いは何ですか?
質問
とはどのような違いがあるのでしょうか?
let
と
before
のブロックをRSpecで作成することはできますか?
そして、それぞれをいつ使うか?
以下の例では、どのようなアプローチ(letまたはbefore)が良いのでしょうか?
let(:user) { User.make !}
let(:account) {user.account.make!}
before(:each) do
@user = User.make!
@account = @user.account.make!
end
私はこれを勉強しました スタックオーバーフローの投稿
しかし、上記のような関連付けのためにletを定義するのは良いことなのでしょうか?
どのように解決するのですか?
人は、基本的な違いについて説明しているようですが、省かれているのは
before(:all)
を省き、なぜそれらを使うべきかを正確に説明していないようです。
で述べたような理由もあり、インスタンス変数は大部分の仕様で使用する場所がないと私は考えています。 この回答 で述べた理由もあり、ここでは選択肢として言及しません。
ブロック化する
の中のコード
let
ブロック内のコードは参照されたときのみ実行され、レイジーローディングではこれらのブロックの順序は関係ありません。これは、仕様を通して繰り返される設定を削減する大きな力を与えてくれます。
これの 1 つの (極めて小規模で作為的な) 例を挙げます。
let(:person) { build(:person) }
subject(:result) { Library.calculate_awesome(person, has_moustache) }
context 'with a moustache' do
let(:has_moustache) { true }
its(:awesome?) { should be_true }
end
context 'without a moustache' do
let(:has_moustache) { false }
its(:awesome?) { should be_false }
end
を見ればわかるように
has_moustache
はそれぞれ異なる定義をしていますが、繰り返し書く必要はありません。
subject
の定義を繰り返す必要はありません。注意すべきことは、最後の
let
ブロックが使用されることです。これは、ほとんどの仕様に使用されるデフォルトを設定するのに適しており、必要に応じて上書きすることができます。
の戻り値のチェックは、例えば
calculate_awesome
を渡された場合
person
を持つモデル
top_hat
を true に設定しても、口ひげはないでしょう。
context 'without a moustache but with a top hat' do
let(:has_moustache) { false }
let(:person) { build(:person, top_hat: true) }
its(:awesome?) { should be_true }
end
let ブロックについてもう一つ注意すべきことは、データベースに保存されているものを検索する場合には使用しないことです (すなわち、let ブロックは
Library.find_awesome_people(search_criteria)
のように) データベースに保存されているものを検索する場合には、 使ってはいけません。なぜなら、すでに参照されていない限り、 データベースには保存されないからです。
let!
または
before
のようなブロックが使用されます。
また
は決して
決して
使用
before
の実行をトリガーするために
let
ブロックの実行をトリガするために、このような
let!
はそのために作られたのです!
ブロック
let!
ブロックは定義された順に実行されます (before ブロックとほぼ同じです)。beforeブロックとの違いは、インスタンス変数にフォールバックする必要がなく、この変数への明示的な参照を得ることができる点です。
と同様に
let
ブロックと同様に、複数の
let!
ブロックが定義されている場合、最新のものが実行時に使用されます。主な違いは
let!
ブロックは複数回実行されます。
let
ブロックは最後の一回だけ実行されます。
before(:each) ブロック
before(:each)
はデフォルトのbeforeブロックであるため、以下のように参照することができます。
before {}
と指定するのではなく、完全な
before(:each) {}
を毎回指定する必要はありません。
個人的な好みとして
before
ブロックを使用するのは、いくつかのコアな状況においてです。私は、もしもの時はbeforeブロックを使用します。
- モッキング、スタブ、またはダブルを使用している。
- 合理的な大きさの設定がある (一般にこれはファクトリーの特性が正しく設定されていないサインです)
- 直接参照する必要はないが、セットアップに必要な変数がいくつかある。
-
私はrailsで機能的なコントローラのテストを書いていて、テストするために特定のリクエストを実行したいです(つまり
before { get :index }
). を使うことができるにもかかわらずsubject
を使うこともできますが、参照を必要としない方がより明示的に感じられることがあります。
もしあなたが大きな
before
ブロックを書いている場合は、ファクトリーを確認し、trait とその柔軟性を完全に理解していることを確認してください。
before(:all)ブロック
これらは、現在のコンテキスト(とその子)のspecの前に、一度だけ実行されます。これは、実行と労力を削減できる特定の状況があるため、正しく書かれた場合、大きな利点に使用することができます。
1つの例(実行時間にほとんど影響しません)は、テストのためにENV変数をモック化することです。
お役に立てれば幸いです :)
関連
-
[解決済み] Railsサーバーがポートはすでに使用されていると言う、そのプロセスを殺すにはどうすればよいですか?
-
[解決済み] Rubyの文字列から日付への変換
-
[解決済み] DestroyとDeleteの違い
-
[解決済み] Ruby on Railsでsimple_formを使うさまざまな方法|何が違うの?
-
[解決済み] フェイク、モッキング、スタビングの違いとは?
-
[解決済み] rake db:migrate db:reset とdb:schema:loadの違いについて
-
[解決済み] Jestの'it'と'test'の違いは何ですか?
-
[解決済み] RSpecのlet()はいつ使うのか?
-
[解決済み】ユニットテストと機能テストの違いは何ですか?
-
[解決済み] RSpecのsubjectとletの違いは何ですか?どんな時に使うのか、使わないのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Webpacker::Manifest::MissingEntryError【クローズド
-
[解決済み] Mac OS Xにhomebrewがインストールされているかどうかを確認する方法
-
[解決済み] デバイスを使用する現在のユーザーメソッド
-
[解決済み] rake db:migrateを使って1ステップだけロールバックする方法
-
[解決済み] ウェブパッカーがアプリケーションを見つけ出せない
-
[解決済み] どなたか、collection_selectをわかりやすく説明していただけませんか?
-
[解決済み] RoRにおけるSpringサーバーの機能とは?
-
[解決済み] Rails 4で、以前のバージョンのRailsでattr_accessibleを使用していた状況に遭遇した場合、Forbidden Attributes Errorが発生する。
-
[解決済み] Railsコンソール:リロード!モデルファイルの変更が反映されない?考えられる理由は何でしょうか?
-
[解決済み] RSpecのlet()はいつ使うのか?