2010-12-07 19 views
31

rspecでfind_each呼び出しをテストする方法が不思議でした。私は単に私がこのようなDBにテストデータに依存しない、私は私のモデルを返すようにしたいものをスタブするために使用しています:レールでrspecテストのためにfind_eachをスタブする方法3

MyClass.stub(:find).and_return(my_mock) 

しかし、別のクラスでは、私は、このやっている:

をスペックテストで

MyClass.stub(:find_each).and_return([one_mock, two_mock]) 

、「ここで何かをやる」の部分が実行されていない:

MyClass.find_each do |instance_of_my_class| 
    do_stuff_here_on(instance_of_my_class) 
end 

は、私がこれを行う場合ことがわかります。誰でもrspecテストのためにfind_eachをスタブする方法を知っていますか?

答えて

35

MyClass.stub(:find_each).and_yield(one_mock).and_yield(two_mock) 
+0

これを行うと、次のエラーが発生します。 1のアリティでブロックする。 私は配列としてモックを渡すと問題はありませんが、find_eachブロックのinstance_of_my_classは配列であり、その中の要素ではありません。 – Aaron

+4

'.and_yield(one_mock).and_yield(two_mock)'はどうですか? – zetetic

+0

あなたは大丈夫です、zetetic - 私はあなたの訂正を含めるために私の答えを編集しました。 – Iain

2

メソッドをスタブする全体のポイントは、メソッドが期待値を返し、その内容を実行しないようにすることです。 find_eachメソッド内にたくさんのロジックがある場合は、別のメソッドに移動し、そのロジックを個別にテストすることをお勧めします。実行中にメソッドが呼び出されたことをテストできます。

ここでは、かなり高いレベルの例です:

class Example1 
    def my_method 
    # some logic 
    end 
end 

class Example2 
    def my_other_method 
    Example1.find_each(&:my_method) 
    end 
end 

RSPEC:あなたはRSpecのモックに渡されたブロックを呼び出す作るためにand_yield使用することができます

describe Example1 do 
    it "should return something" do 
    example = Example1.new 
    example.my_method.should == something 
    end 
end 

describe Example2 do 
    it "should call my_method on Example1" do 
    example1 = mock(:example1, :my_method => true) 
    example2 = Example2.new 

    example1.should_receive(:my_method) 
    example2.my_other_method 
    end 
end 
+0

。私はこれを反映するために私の質問のfind_eachブロックを更新しました。私は、私が渡したすべてのモックでこれを実行するかどうかテストしようとしています。 – Aaron

1

このそれを行う必要があります:

MyClass.stub(:find_each) {|block| 
    block.call 
    [one_mock, two_mock] 
} 

do_stuff_here_onにグローバルに到達できません。 some_objectのインスタンスメソッドは、あなたはブロックのための右の範囲を得るために、いくつかのinstance_evalをする必要があります:私は実際に私がテストしています別の方法でロジックをやってる

MyClass.stub(:find_each) {|block| 
    some_object.instance_eval(&block) 
    [one_mock, two_mock] 
} 
関連する問題