有没有一种方法可以使用Rspec对包含的模块的方法进行存根? [英] Is there a way to stub a method of an included module with Rspec?

查看:68
本文介绍了有没有一种方法可以使用Rspec对包含的模块的方法进行存根?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模块包含在另一个模块中,并且它们都实现相同的方法. 我想对包含的模块的方法进行存根,如下所示:

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?

谢谢!

------------------------------------- UPDATE --------- -------------------------

-------------------------------------UPDATE----------------------------------

谢谢!使用allow_any_instance_of(M)解决了这一问题. 我的下一个问题是-如果我使用前置而不包括在内会怎样?请参阅以下代码:

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:

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)导致无限循环.这是为什么?

This time, using allow_any_instance_of(M) results in an infinite loop. why is that?

推荐答案

请注意,您不能直接调用M.foo!您的代码似乎仅能正​​常工作,因为您嘲笑了M.foo返回:bar.

Note you cannot directly call M.foo! Your code only seems to work because you mocked M.foo to return :bar.

当打开A元类(class << self)以包含M时,您必须模拟M的任何实例,该实例将添加到您的before块中:

When you open A metaclass (class << self) to include M, you have to mock any instance of M, that is adding to your before block:

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

这篇关于有没有一种方法可以使用Rspec对包含的模块的方法进行存根?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆