2017-04-27 10 views
-2

を呼び出しシミュレート:スペックで次にRSpecのは、私はこのようにそれをやっている私はRSpecの でテストしています関数の引数を呼び出してシミュレートすることができますどのように関数の引数

module Module1 
    def find_item(str, item_class) 
    arr = item_class.find_or_initialize_by(...) 
    end 
end 

let!(:dummy_class) { Class.new { extend Module1 } } 

it 'calls find_or_initialize_by' do 
    item_class = double("Item") 
    allow(dummy_class).to receive(:item_class).and_return(item_class) 
    expect(item_class).to receive(:find_or_initialize_by) 
    dummy_class.find_item("item1", Item) 
end 

そして、「#は実装されていません:item_class」というエラーが発生します class_doubleとinstance_doubleを使用しようとしていましたが、役に立たなかったです。

Failures:

1) Module1#find_items Failure/Error: allow(dummy_class).to receive(:item_class) # does not implement: item_class # ./spec/..._spec.rb:26:in `block (3 levels) in '

26行:(:item_class)なぜあなたはそれについてこの道を進んでいるが、あなたはあまりにも遠くはありません.and_return(item_class)

+0

をこんにちは、あなたは詳細を追加することができますあなたが得るエラー? – Bohdan

+0

私の投稿を更新しました – andgursky

+0

http://stackoverflow.com/help/accepted-answer – engineersmnky

答えて

1

わからない受信.TO(dummy_class)を可能にします。

現在、あなたは

allow(dummy_class).to receive(:item_class).and_return(item_class) 

が、item_classを使用しようとしているが、それだけでlocal_variableある方法ではありません。一言で言えば

Message Allowance構文構文はexpect(object).to receive(method_name).with(arguments).and_return(return_value)

あるので、多分あなたは何を意味するのかfind_item以来allow(dummy_class).to receive(:find_item).with(item_class).and_return(item_class)allow(object).to receive(method_name).with(arguments).and_return(return_value)

Message Expectationある方法は、実際に呼び出されて、あなたがしているので、item_classは、渡された引数であるが、戻り値をスタブすると、メソッド本体が決して発生しません。

allow(dummy_class).to recieve(:find_item).and_call_originalこれ以上のことがありますが、dummy_classはダブルではなく、既にfind_itemの元のバージョンを呼び出すことを「許可」されているため、これは実際に目的を果たしません。

ネイティブ機能をdummy_classとし、ちょうどallow(item_class).to receive(:find_or_initialize_by)とすると、次のように動作します。

it 'calls find_or_initialize_by' do 
    item_class = double("Item") 
    allow(item_class).to recieve(:find_or_initialize_by) #needed because it is a test double and knows nothing 
    expect(item_class).to receive(:find_or_initialize_by) 
    dummy_class.find_item("item1", item_class) #used test double here to trap messages 
end 

代わりに、我々はItemの部分的な二重を使用してTest Doubleitem_class例えばをスキップすることができます

#please note this binds the test to Item existing 
it 'calls find_or_initialize_by' do 
    allow(Item).to receive(:find_or_initialize_by) #now a stubbed method on a partial double(Item) 
    expect(Item).to receive(:find_or_initialize_by) 
    dummy_class.find_item("item1", Item) #used the partial double 
end 

Partial doubles彼らはダブルスを検証することができ、Objectが実際にそれをスタブする前に、そのメソッドを定義して確認しますので、いいです。なぜなら、彼らはあなたのテストの性質とdummy_classが二重ではないという事実(allow何もすることは必要はありません)与えられたとされていると、あなただけのコール任意の戻り値をテストしていない、私はちょうどSpyを使用することをお勧めだろうと

単にメッセージの期待のためのものです。 これはテストは、単純明確にし、すべての依存関係の自由ます:

it 'calls find_or_initialize_by' do 
    item = spy("item") 
    dummy_class.find_item("item1", item) 
    expect(item).to have_received(:find_or_initialize_by) 
end 

は、彼らはあまりにも部分的な二重の味に来るが、これはItemが知られており、Objectをロードしているに依存している:上記の(非常に似ていますが、期待呼び出しの効果後)

#please note this binds the test to Item existing 
it 'calls find_or_initialize_by' do 
    allow(Item).to receive(:find_or_initialize_by) 
    dummy_class.find_item("item1", Item) 
    expect(Item).to have_received(:find_or_initialize_by) 
end 

はまた、私はそれがうまくなどとして適切な引数で呼び出されたことをテストを示唆しているのは、Module1(...)name: strのように見えると仮定しましょう

これにより、コールが行われただけでなく、予想される引数がコールに渡されたことが保証されます。それはあなたのテストが独立し、速いなるため

特にメッセージの期待のModuleテストで私は(Itemがもう存在しないとどうなるんでしょうか?)テストダブルスとスパイに維持しようとする

関連する問題