db データに依存するテストがあります。rspec describe ブロックの before ステートメントを使用して、ファクトリを使用してオンザフライでデータを作成してきました。
それらを実行の開始点に移動したいと思います。工場を使い続けながらこれを行う良い方法はありますか?
はい、これにアプローチするにはいくつかの方法があります。デフォルトでは、RSpec 構文
before do
end
と同じです
before :each do
end
これは、before ブロック内のコードが各仕様の前に呼び出されることを意味します。
ただし、次のものも使用できます。
before :all do
#...
end
これは、それが定義されている記述 (またはそのエイリアス コンテキスト) ブロックに対して、囲んでいるコードを 1 回実行します。ただし、ブロックbefore :all
で定義する内容によっては、テストが分離して実行されなくなるため、注意して使用する必要があります。before :all
スイート全体の前に 1 回実行されるコードを書きたい場合は、spec_helper ファイル内の RSpec 構成内で定義できるオプション before(:suite) および after(:suite) もあります。
より一般的なアプローチは、1 つの引数と 1 つのブロックを受け入れる 'let' と呼ばれる RSpec メソッドを使用することです。次のようになります。
let(:foo) { FactoryGirl.create :user }
簡単に言えば、メソッドは、返されるブロックの値を返すlet
メソッド エイリアスを作成します (上の例では)。利点は、(1) この変数をキャッシュするため、ブロックは 1 回だけ取得され、(2) 遅延評価されるため、テスト内で foo が呼び出されたときにのみ実行され、ブロック内の値がキャッシュされます。この遅延評価は、場合によっては予期しない動作を引き起こす可能性があることを覚えておくことが重要です。代わりに使用して、遅延読み込みを防ぐことができます。メソッドはステートメントの前に実行されるため、ブロックで定義された任意のメソッドを使用できます。foo
FactoryGirl.create :user
let!
let
before
let
before
最後に、一度だけ実行されるジェネレーターを spec_helper で定義できる FactoryGirl Seeds というプロジェクトがあります。個人的にはあまり使用していないため、信頼性についてはわかりませんが、詳細については次を参照してください。