Похоже, что стандартный способ использовать mocks rspec в тестовом примере - это сделать что-то вроде этого:
class MyTest
def setup
super
::RSpec::Mocks.setup(self)
end
def teardown
super
begin
::RSpec::Mocks.verify
ensure
::RSpec::Mocks.teardown
end
end
test "something"
foo = MyFoo.new
expect(foo).to receive(:bar).and_return(42)
ret = SomeClass.call_bar(foo)
assert_equal(42, ret)
end
end
Это работает хорошо . Но если SomeClass.call_bar
использовал возврат foo.bar
в качестве возврата и что-то не так с кодом, так что foo.bar
никогда не вызывался, то я получаю только сбой из-за строки assert_equal(42, ret)
. Я не вижу никакой ошибки как:
RSpec::Mocks::MockExpectationError: (foo).bar
expected: 1 time
received: 0 times
Если я удалю строку assert_equal(42, ret)
, то получу ошибку ожидания rspec. Но я хочу проверить обе вещи: foo.bar
был назван и , окончательное возвращение было 42. Более важно знать, что foo.bar
не вызывали, так как это источник причины, по которой 42 не был не вернулся.
Если я ожидаю что-то вроде: expect(foo).not_to receive(:bar)
, тогда я получаю эту ошибку ожидания прямо в источнике вызова, а не позже во время разрыва.
Теперь я могу сделать что-то вроде put ::RSpec::Mocks.verify
непосредственно перед вызовом assert_equal
, но это не так. Я также не уверен, должен ли я убирать издевательства в этот момент или нет.
Есть ли такой синтаксис, как:
test "something"
foo = MyFoo.new
ret = nil
expect(foo).to receive(:bar).and_return(42).during do
ret = SomeClass.call_bar(foo)
end
assert_equal(42, ret)
end
Так что проверка происходит сразу после того, как блок перешел на during
? Или, может быть, если у вас есть несколько двойных, вы можете сделать что-то вроде:
expect(dbl1).to receive(:one)
expect(dbl2).to receive(:two)
expect(dbl3).to receive(:three)
verify(dbl1, dbl2, dbl3).during do
my_code
end