ruby 有没有办法用 Rspec 存根包含模块的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24408717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to stub a method of an included module with Rspec?
提问by user3775153
I have a module that is included in another module, and they both implement the same method. I would like to stub the method of the included module, something like this:
我有一个包含在另一个模块中的模块,它们都实现了相同的方法。我想存根包含模块的方法,如下所示:
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
The first test is passing, but the second one outputs:
第一个测试通过,但第二个输出:
Failure/Error: expect(A.foo).to eq :bar
expected: :bar
got: :M
Why isn't the stub working in this case? Is there a different way to achieve this?
为什么在这种情况下存根不起作用?有没有不同的方法来实现这一目标?
Thanks!
谢谢!
-------------------------------------UPDATE----------------------------------
- - - - - - - - - - - - - - - - - - -更新 - - - - - - ---------------
Thanks! using allow_any_instance_of(M) solved this one. My next question is - what happens if I use prepend and not include? see the following code:
谢谢!使用 allow_any_instance_of(M) 解决了这个问题。我的下一个问题是 - 如果我使用前置而不包括会发生什么?请参阅以下代码:
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
This time, using allow_any_instance_of(M) results in an infinite loop. why is that?
这一次,使用 allow_any_instance_of(M) 会导致无限循环。这是为什么?
回答by mdemolin
Note you cannot directly call M.foo! Your code only seems to work because you mocked M.footo return :bar.
请注意,您不能直接调用M.foo!您的代码似乎只能工作,因为您嘲笑M.fooreturn :bar。
When you open Ametaclass (class << self) to include M, you have to mock any instance of M, that is adding to your beforeblock:
当您打开A元类 ( class << self) 以包含 时M,您必须模拟 的任何实例M,即添加到您的before块中:
allow_any_instance_of(M).to receive(:foo).and_return(:bar)
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

