有没有办法用Rspec存根包含模块的方法?
我有一个包含在另一个模块中的模块,它们都实现了相同的方法。 我想存根包含模块的方法,如下所示:
module M def foo :M end end module A class << self include M def foo super end end end describe "trying to stub the included method" do before { allow(M).to receive(:foo).and_return(:bar) } it "should be stubbed when calling M" do expect(M.foo).to eq :bar end it "should be stubbed when calling A" do expect(A.foo).to eq :bar end end
第一个测试是通过,但第二个测试输出:
Failure/Error: expect(A.foo).to eq :bar expected: :bar got: :M
为什么在这种情况下存根不工作? 有没有不同的方法来实现这一目标?
谢谢!
————————————- UPDATE ———— ———————-
谢谢! 使用allow_any_instance_of(M)解决了这个问题。 我的下一个问题是 – 如果我使用prepend而不包括会发生什么? 请参阅以下代码:
module M def foo super end end module A class << self prepend M def foo :A end end end describe "trying to stub the included method" do before { allow_any_instance_of(M).to receive(:foo).and_return(:bar) } it "should be stubbed when calling A" do expect(A.foo).to eq :bar end end
这次,使用allow_any_instance_of(M)会导致无限循环。 这是为什么?
注意你不能直接打电话给M.foo
! 你的代码似乎只是起作用,因为你嘲笑M.foo
返回:bar
。
当你打开A
元类( class << self
)来包含M
,你必须模拟M
任何实例,即添加到你的before
块:
allow_any_instance_of(M).to receive(:foo).and_return(:bar)
module M def foo :M end end module A class << self include M def foo super end end end describe "trying to stub the included method" do before do allow(M).to receive(:foo).and_return(:bar) allow_any_instance_of(M).to receive(:foo).and_return(:bar) end it "should be stubbed when calling M" do expect(M.foo).to eq :bar end it "should be stubbed when calling A" do expect(A.foo).to eq :bar end end