Rspec 3.0 Как имитировать метод, заменяющий параметр, но без возвращаемого значения?

Я много искал и просто не могу понять это, хотя это кажется простым. Вот упрощенный пример того, что я хочу сделать.

Создайте простой метод, который что-то делает, но ничего не возвращает, например:

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

If I do:

@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)

не разрешено.


person user3060126    schedule 18.04.2014    source источник
comment
Ваше сообщение об ошибке кажется обратным вашему заглушке.   -  person Andrew Marshall    schedule 18.04.2014


Ответы (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

Похоже, вы пытаетесь настроить тестовый шпион на метод, но тогда я думаю, что вы настраиваете заглушку метода на один уровень выше (на самом test_method вместо вызова puts внутри test_method). Если поставить заглушку на вызов 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
person Paul Fioravanti    schedule 18.04.2014
comment
Спасибо - это полезно! Во-первых, я не знал, что вы можете сказать expect(test).to receive(:puts) - я думал, что вы можете вызывать только прямой метод (здесь test_method), так что это полезно знать. В конце концов, моя реальная проблема оказалась более сложной, и я решил, что мне просто нужно изменить свой код, чтобы определить метод, который действительно возвращает значение, что, вероятно, в любом случае является лучшей практикой. И тогда легко использовать allow(test).to receive(:test_method).and_return('goodbye'). Я уверен, что есть другой способ использовать кое-что из этого, и также полезно знать о тестовых шпионах — я не сталкивался с этим раньше. - person user3060126; 18.04.2014

Как установить значение по умолчанию, которое объясняется на

and_call_original может настроить ответ по умолчанию, который можно переопределить для определенных аргументов

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.

person Jignesh Gohel    schedule 30.03.2017