Ответ 1
В настоящий момент (rspec-mocks 2.10.1) нет метода, эквивалентного unstub
, но для should_receive
. Вы можете reset все заглушки и макеты с помощью rspec_reset
, и вы также можете писать грязные хаки, чтобы удалить определенное ожидание (которое я бы не рекомендовал).
Ниже приведен пример удаления всех заглушек и ожиданий объекта:
describe "resetting stubs and expectations with rspec_reset" do
before do
@person = mock('person')
@person.should_receive(:poke)
end
it "should not fail when we reset all stubs and expectations" do
@person.rspec_reset
end
end
Обратите внимание, что этот метод аннотируется в исходном коде rspec как @private
, что означает, что вам следует избегать его использования более чем абсолютно необходимо, и он может нарушать в будущих версиях rspec без предупреждения. Это, однако, довольно широко используется в спецификациях для самого rspec, поэтому представляется менее вероятным, что это будет устаревшим в ближайшее время.
После копания кода rspec-mocks немного больше, вы можете, конечно, сделать что-то действительно неприятное и вырвать одно конкретное ожидание:
# Works in rspec 2.10.1
describe "removing an expectation with an ugly hack" do
before do
@person = mock('person')
@person.should_receive(:poke)
end
it "should not fail after we hack rspec by violating every law of good programming, ever" do
@person.instance_variable_get(:@mock_proxy).instance_variable_get(:@method_double)[:poke].clear
end
end
Это действительно плохо, так как это нарушает инкапсуляцию тестового пакета rspec, и вы не должны этого делать. Вместо этого, если у вас действительно была веская причина удалить определенное ожидание, правильным было бы добавить открытый метод вверх по течению в rspec-mocks, который добавит параллельный метод к unstub
, но для устранения определенных ожиданий. Вероятно, он находится здесь (обратите внимание на определение stub
и unstub
, а также в этом файле):
https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/methods.rb
Перед тем, как выйти и использовать любое из приведенных выше предложений для устранения ожидаемого ожидания, вы можете подумать, действительно ли ваши спецификации действительно должны это сделать или если они должны быть реорганизованы. Использование should_receive
- это утверждение о вашем коде, и обычно вам следует попытаться создать примеры (т.е. it
blocks), которые утверждают только одно. Мне было бы очень интересно, почему вам нужно что-то вроде rspec_reset
, если вы не пытаетесь сделать слишком много в глобальной настройке (например, before :each
или до: все блоки), или если ваши примеры пытаются сделать слишком много (т.е. с несколькими утверждениями в одном примере).
Единственное исключение из этого может быть, конечно, в наборе тестов rspec-mocks, где rspec_reset
используется для состояния reset между примерами, которые проверяют функциональность применения заглушек и mocks. Если вы этого не сделаете, скорее всего, ваши тесты могут быть улучшены, чтобы не полагаться на глобальные сбросы заглушек и mocks на объект.
Я надеюсь, что это поможет и, пожалуйста, сообщите мне, если вы считаете, что существует законный случай добавления эквивалентного метода к unstub
, а для ожиданий сообщений (т.е. после использования should_receive
). Если я убежден, что это нормально, я бы хотел добавить этот метод и предложить его добавить вверх по течению. Может быть, это называется unset_expectation
? Пожалуйста, также не стесняйтесь использовать руководство для кода и внутренних структур выше, чтобы собрать запрос на вытягивание для rspec-mocks самостоятельно, и мы увидим, принимается ли он, чтобы создать насмешливый эквивалент unstub
.