问题 如何模拟Ruby模块功能?


如何在项目中模拟自编写模块的模块功能?

鉴于模块和功能

module ModuleA::ModuleB
  def self.my_function( arg )
  end
end

这就是所谓的

ModuleA::ModuleB::my_function( with_args )

当我在编写规范的函数中使用它时,我应该如何模拟它?


加倍(obj = double("ModuleA::ModuleB"))对我来说没有意义,因为函数是在模块上调用而不是在对象上调用。

我试过掐它(ModuleA::ModuleB.stub(:my_function).with(arg).and_return(something))。显然,它没有用。 stub 那里没有定义。

然后我试了一下 should_receive。再次 NoMethodError

模拟模块及其功能的首选方法是什么?


4761
2017-07-05 21:50


起源



答案:


给出您在问题中描述的模块

module ModuleA ; end

module ModuleA::ModuleB
  def self.my_function( arg )
  end
end

和被测函数,它调用模块函数

def foo(arg)
  ModuleA::ModuleB.my_function(arg)
end

然后你可以测试一下 foo 电话 myfunction 喜欢这个:

describe :foo do
  it "should delegate to myfunction" do
    arg = mock 'arg'
    result = mock 'result'
    ModuleA::ModuleB.should_receive(:my_function).with(arg).and_return(result)
    foo(arg).should == result
  end
end

11
2017-07-06 00:49



这基本上就是我尝试过的。谢谢你的总结。然而我的问题是,我把它放了 should_receive 在一个 before :all 块。显然这不起作用。我多么愚蠢 - Torbjörn
@Torbjoern,哦,是的。到过那里。很高兴你得到了它。 - Wayne Conrad
在当前的rspec(3.6)中,它给出了“使用 should_receive 来自rspec-mocks的旧 :should 不支持显式启用语法的语法。使用新的 :expect 语法或显式启用 :should 代替。” - Mateusz Konieczny


答案:


给出您在问题中描述的模块

module ModuleA ; end

module ModuleA::ModuleB
  def self.my_function( arg )
  end
end

和被测函数,它调用模块函数

def foo(arg)
  ModuleA::ModuleB.my_function(arg)
end

然后你可以测试一下 foo 电话 myfunction 喜欢这个:

describe :foo do
  it "should delegate to myfunction" do
    arg = mock 'arg'
    result = mock 'result'
    ModuleA::ModuleB.should_receive(:my_function).with(arg).and_return(result)
    foo(arg).should == result
  end
end

11
2017-07-06 00:49



这基本上就是我尝试过的。谢谢你的总结。然而我的问题是,我把它放了 should_receive 在一个 before :all 块。显然这不起作用。我多么愚蠢 - Torbjörn
@Torbjoern,哦,是的。到过那里。很高兴你得到了它。 - Wayne Conrad
在当前的rspec(3.6)中,它给出了“使用 should_receive 来自rspec-mocks的旧 :should 不支持显式启用语法的语法。使用新的 :expect 语法或显式启用 :should 代替。” - Mateusz Konieczny


对于rspec 3.6,请参阅 如何在RSpec中模拟类方法期望语法?

为了避免仅链接答案,这里是Andrey Deineko的答案副本:

allow(Module)
  .to receive(:profile)
  .with("token")
  .and_return({"name" => "Hello", "id" => "14314141", "email" => "hello@me.com"})

0
2018-06-06 10:12