Rspec 3.0如何模拟替换参数但没有返回值的方法?

use*_*126 12 ruby rspec mocking stubbing

我已经搜索了很多,虽然看起来很基本,但却无法解决这个问题.这是我想要做的简化示例.

创建一个执行某些操作但不返回任何内容的简单方法,例如:

class Test
  def test_method(param)
    puts param
  end
  test_method("hello")
end
Run Code Online (Sandbox Code Playgroud)

但在我的rspec测试中,我需要传递一个不同的参数,例如"goodbye"而不是"hello".我知道这与存根和模拟有关,我查看了文档,但无法弄明白:https : //relishapp.com/rspec/rspec-mocks/v/3-0/docs/method -stubs

如果我做:

@test = Test.new
allow(@test).to_receive(:test_method).with("goodbye")
Run Code Online (Sandbox Code Playgroud)

它告诉我存根一个默认值,但我无法弄清楚如何正确地做到这一点.

错误信息:

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.     
Run Code Online (Sandbox Code Playgroud)

我正在使用rspec 3.0,并调用类似的东西

@test.stub(:test_method)
Run Code Online (Sandbox Code Playgroud)

不被允许.

Jig*_*hel 15

如何设置解释的默认值

and_call_original 可以配置可以覆盖特定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
Run Code Online (Sandbox Code Playgroud)

我所知道的来源可以在https://makandracards.com/makandra/30543-rspec-only-stub-a-method-when-a-particular-argument-is-passed找到


Pau*_*nti 2

对于您的示例,由于您不需要测试 的实际结果test_method,只需puts在传入 时调用它param,我只需通过设置期望并运行该方法来进行测试:

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
Run Code Online (Sandbox Code Playgroud)

您似乎试图做的是在该方法上设置一个测试间谍,但后来我认为您将方法存根设置得太高了一级(在其本身上而不是对insidetest_method的调用)。如果您将存根放在对 的调用上,您的测试应该通过:putstest_methodputs

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
Run Code Online (Sandbox Code Playgroud)