似乎在测试用例中使用 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
使用 return offoo.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)
,那么我确实在调用的源头得到了那个期望错误,而不是在拆解的后期。
现在,我可以::RSpec::Mocks.verify
在调用 to 之前执行 put 之类的操作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