Rspec 3.0 如何模拟替换参数但没有返回值的方法?
Posted
技术标签:
【中文标题】Rspec 3.0 如何模拟替换参数但没有返回值的方法?【英文标题】:Rspec 3.0 How to mock a method replacing the parameter but with no return value? 【发布时间】:2014-06-02 12:06:48 【问题描述】:我已经搜索了很多,但无法弄清楚,尽管它看起来很基本。这是我想要做的简化示例。
创建一个做某事但不返回任何内容的简单方法,例如:
class Test
def test_method(param)
puts param
end
test_method("hello")
end
但在我的 rspec 测试中,我需要传递不同的参数,例如“再见”而不是“你好”。我知道这与存根和模拟有关,我查看了文档但无法弄清楚:https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/method-stubs
如果我这样做:
@test = Test.new
allow(@test).to_receive(:test_method).with("goodbye")
它告诉我存根一个默认值,但我不知道如何正确地做到这一点。
错误信息:
received :test_method with unexpected arguments
expected: ("hello")
got: ("goodbye")
Please stub a default value first if message might be received with other args as well.
我正在使用 rspec 3.0,并调用类似
@test.stub(:test_method)
不允许。
【问题讨论】:
您的错误信息似乎与您的存根相反。 【参考方案1】:如何设置默认值,详见
and_call_original
can configure a default response that can be overriden for specific args
require 'calculator'
RSpec.describe "and_call_original" do
it "can be overriden for specific arguments using #with" do
allow(Calculator).to receive(:add).and_call_original
allow(Calculator).to receive(:add).with(2, 3).and_return(-5)
expect(Calculator.add(2, 2)).to eq(4)
expect(Calculator.add(2, 3)).to eq(-5)
end
end
我知道的来源可以在https://makandracards.com/makandra/30543-rspec-only-stub-a-method-when-a-particular-argument-is-passed找到
【讨论】:
【参考方案2】:对于您的示例,由于您不需要测试 test_method
的实际结果,只有在 param
中调用 puts
时,我将通过设置期望并运行方法:
class Test
def test_method(param)
puts param
end
end
describe Test do
let(:test) Test.new
it 'says hello via expectation' do
expect(test).to receive(:puts).with('hello')
test.test_method('hello')
end
it 'says goodbye via expectation' do
expect(test).to receive(:puts).with('goodbye')
test.test_method('goodbye')
end
end
您似乎正在尝试在该方法上设置一个test spy,但我认为您将方法存根设置一个级别太高(在@987654326 @ 本身,而不是在 test_method
中调用 puts
)。如果您将存根放在对puts
的调用中,您的测试应该通过:
describe Test do
let(:test) Test.new
it 'says hello using a test spy' do
allow(test).to receive(:puts).with('hello')
test.test_method('hello')
expect(test).to have_received(:puts).with('hello')
end
it 'says goodbye using a test spy' do
allow(test).to receive(:puts).with('goodbye')
test.test_method('goodbye')
expect(test).to have_received(:puts).with('goodbye')
end
end
【讨论】:
谢谢 - 这很有帮助!一方面,我不知道您可以说expect(test).to receive(:puts)
- 我以为您只能调用直接方法(此处为test_method
),所以很高兴知道。最后,我的实际问题更复杂,我决定只需要更改我的代码来定义 确实 返回值的方法,无论如何这可能是更好的做法。然后很容易使用allow(test).to receive(:test_method).and_return('goodbye')
。我确信还有另一种方法可以使用其中的一些,而且了解测试间谍也很好 - 我以前没有遇到过。以上是关于Rspec 3.0 如何模拟替换参数但没有返回值的方法?的主要内容,如果未能解决你的问题,请参考以下文章
模拟 Rails.env.development?使用 rspec
Rails 4, RSpec 3.2 - 如何模拟 ActionMailer 的 Deliver_now 方法来引发异常