【发布时间】:2019-06-27 14:31:27
【问题描述】:
似乎在测试用例中使用 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),那么我确实会在调用源处得到该期望错误,而不是在拆卸过程中稍后。
现在,我可以在调用assert_equal 之前添加::RSpec::Mocks.verify,但这感觉不对。我也不确定此时是否应该清理模拟。
有没有类似的语法:
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
【问题讨论】:
标签: ruby unit-testing rspec rspec-mocks