10

継承されたアプリのテストを理解しようとしていますが、助けが必要です。

このような仕様グループがたくさんあります (仕様を表示):

let(:job_post) { FactoryGirl.create(:job_post) }

# ...

before do
  expect(view).to receive(:job_post).at_least(:once).and_return(job_post)
end

it "should render without error" do
  render
end

...job_postコントローラーで定義されたヘルパーメソッドです。(はい、@instance 変数を使用できた可能性があります。私はそれをリファクタリング中です)。

さて、私の意見では、ブロックexpect内を使用するのは間違っています。beforeちょっと忘れてみましょう。

通常、上記のテストは緑色です。
ただし、行を削除するexpectと、テストは失敗します。この場合expect、ビューでメソッドをスタブ化しているようです。実際、に置き換えるexpectallowまったく同じ効果があるようです。

通常、サーバーで実行すると、ビューが呼び出さjob_postsれ、メッセージがコントローラーのヘルパー メソッドに送られます。これは、予想される動作です。

ただし、ここではexpect期待値を設定すると同時に、view固定の戻り値でメソッドをスタブ化しています。ビュー テンプレートそのメソッドを呼び出すため、テストはパスします。

の予想外の「スタブ」副作用について、 rspec-mocks readmeexpectでこれを見つけました。

(...) find が呼び出されない場合に例が失敗するように、メッセージの期待値を設定することもできます。

person = double("person")
expect(Person).to receive(:find) { person }

RSpecは、スタブまたはモックしているメソッドを独自の test-double のようなメソッドに置き換えます。例の最後で、RSpec はメッセージの期待値を検証し、元のメソッドを復元します。

メソッドのこの特定の使用に関する経験はありますか?

4

3 に答える 3

24

まあ、それは何をするかexpect().to receive()です!これは の (そうではない) 新しい期待構文であり、 APIrspecを置き換えますshould_receive

expect(view).to receive(:job_post).at_least(:once).and_return(job_post)

と同等です

view.should_receive(:job_post).at_least(:once).and_return(job_post)

この API は期待値戻り値を設定します。これがデフォルトの動作です。元のメソッドも実際に呼び出すには、次のように明示的に指定する必要があります。

view.should_receive(:job_post).at_least(:once).and_call_original

他のいくつかの問題について:

(はい、@instance 変数を使用できた可能性があります。私はそれをリファクタリング中です)。

letAPI は rspec テストで非常に遍在しており、多くの場合 @instance 変数よりも優れている可能性があります (たとえば、遅延型であるため、必要な場合にのみ実行され、メモ化されているため、多くても 1 回実行されます)。

実際、に置き換えるexpectallowまったく同じ効果があるようです。

このallow構文はstub、古い rspec 構文のメソッドを置き換えるため、同じ効果がありますが、違いは、スタブ化されたメソッドが呼び出されなくてもテストに失敗しないことです。


OPが要求したように - についてのいくつかの説明should_receive- 単体テストは分離して実行されることが期待されています。これは、テストの直接の一部ではないものはすべてテストすべきではないことを意味します。これは、HTTP 呼び出し、IO 読み取り、外部サービス、その他のモジュールなどはテストの一部ではないことを意味し、テストの目的上それらが正しく機能すると想定する必要があります。

テストに含める必要があるのは、これらの HTTP 呼び出し、IO 読み取り、および外部サービス正しく呼び出されることです。これを行うには、メッセージの期待値を設定します。テスト対象のメソッドが特定のメソッドを呼び出すことを期待します(実際の機能はテストの範囲外です)。したがって、サービスが正しい引数を使用してメソッド呼び出しを 1 回以上 (呼び出し回数を明示的に期待できます)受け取ることを期待し、実際に呼び出される代わりにそれをスタブし、テストに、その戻り値を設定します。

ソース:

于 2014-03-26T20:14:39.320 に答える