私は最近、Ruby 2.0、Rails 4、および Rspec 2.13.1 でこの奇妙な動作を発見しました。
を使用してインスタンス メソッドをスタブするClassName.any_instance.stub(:method_name)
と、作成した過去のインスタンスが正しくスタブされます。ただし、戻り値を変更して再タブすると、古いインスタンスは新しいスタブ値ではなく、古いスタブ値を返します。
たとえば、このダミーのクラス定義があります
class A
def test(x)
return x
end
end
そして、このテストは動作を説明しています:
it 'strange stubbing behavior' do
inst = A.new
inst.test(1).should eq 1 #passes
A.any_instance.stub(:test).and_return(10)
inst.test(0).should eq 10
A.any_instance.unstub(:test) #has no effect
A.any_instance.stub(:test).and_return(100)
inst.test(0).should eq 100 #expects 100, got 10
A.any_instance.stub(:test) do |a|
a + 2
end
inst.test(3).should eq 5 #also fails # also got 10
end
rspec がこのように動作するのはなぜですか? それは定義された動作ですか?もしそうなら、古いインスタンスを再スタブする適切な方法は何ですか? それともバグですか?
編集:他の誰かが「質問に質問する」という答えを出す前に、仕様を再考して再編成することで元の問題を解決したことを指摘したいと思います。しかし、なぜRSpecがこのように振る舞うかについてはまだ興味があります