Ruby 测试结束前验证rspec模拟
在测试用例中使用rspec模拟的标准方法似乎是这样做:Ruby 测试结束前验证rspec模拟,ruby,unit-testing,rspec,rspec-mocks,Ruby,Unit Testing,Rspec,Rspec Mocks,在测试用例中使用rspec模拟的标准方法似乎是这样做: classmytest def设置 超级的 ::RSpec::Mocks.setup(self) 结束 def拆卸 超级的 开始 ::RSpec::Mocks.verify 确保 ::RSpec::Mocks.teardown 结束 结束 测试“某物” foo=MyFoo.new 期望(foo).接收(:bar.)和返回(42) ret=SomeClass.call\u bar(foo) 断言相等(42,ret) 结束 结束 好的。但是如
classmytest
def设置
超级的
::RSpec::Mocks.setup(self)
结束
def拆卸
超级的
开始
::RSpec::Mocks.verify
确保
::RSpec::Mocks.teardown
结束
结束
测试“某物”
foo=MyFoo.new
期望(foo).接收(:bar.)和返回(42)
ret=SomeClass.call\u bar(foo)
断言相等(42,ret)
结束
结束
好的。但是如果SomeClass.call\u bar
使用foo.bar
的返回作为返回,并且代码出现了一些错误,以至于从未调用过foo.bar
,那么我只会收到由于assert\u 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的事情。在调用assert_equal
之前验证,但这感觉不对。我也不确定我是否应该在这一点上清理模拟
是否有如下语法:
测试“某物”
foo=MyFoo.new
ret=零
预期(foo).在do期间接收(:bar.)和返回(42)
ret=SomeClass.call\u bar(foo)
结束
断言相等(42,ret)
结束
因此,在
期间,验证会在块传递到之后立即进行?或者,如果你有多个替身,你可以这样做:
expect(dbl1).接收(:一)
期望(dbl2).接收(:2)
期望(dbl3).接收(:三)
验证(dbl1、dbl2、dbl3)
我的密码
结束
我不认为有任何内置方法可以做到这一点,但如果您添加以下类:
class VerifyDuring
def initialize(test, objects)
@test = test
@objects = objects
end
def during
yield
ensure
begin
@objects.each do |object|
RSpec::Mocks.proxy_for(object).verify
end
rescue Exception => e
@test.flunk e
end
end
end
并将以下方法应用于测试类:
def verify(*对象)
VerifyDuring.new(自我、对象)
结束
您可以这样做:
验证(dbl1、dbl2、dbl3)
我的密码
结束
您正在寻找的
间谍是支持这一点的另一种双重测试类型
通过使用have\u received
,您可以期望在事件发生后收到消息
您可以使用allow(…)从foo
中创建一个部分double。若要接收
,则可以断言消息的接收:
test "something"
foo = MyFoo.new
allow(foo).to receive(:bar).and_return(42)
ret = SomeClass.call_bar(foo)
expect(foo).to have_received(:bar)
assert_equal(42, ret)
end
我相信你需要的是把失败汇总起来
在“正常”设置中,任何错误都会中止测试,并且不会检查以后的断言 这不会有帮助,因为失败的断言expect(foo)。要接收(:bar)
将中止测试。我不同意这一点;OP指出知道调用没有发生是更重要的断言。我编写的测试,如果没有调用该方法,将导致指示该对象没有收到消息。如果返回的值取决于是否收到消息,则未收到消息始终意味着第二次测试失败。在这种情况下,聚合失败并不能帮助调试失败的原因,而且可能会弄乱局面。哦,对不起。我没有注意到断言顺序的变化。你能编辑一下你的回答吗,这样我就可以删除否决票了?这非常接近,allow
之前的通话,然后expect
之后的通话。。。我会给它一些时间看看是否有其他答案,但这是最接近的答案,可能会被接受。这并没有回答有关如何实际验证消息调用的问题。它仍在拆卸阶段进行验证,这是一个有助于在第一次失败的断言上中止测试的解决方案。这与我所需要的是一致的,但是assert
来自minitest,而expect
来自rspec,所以我认为它们不会聚合在一起。您尝试过吗?聚合意味着测试在第一次失败后不会中止,所以有可能会发生拆卸。我不需要这成为minitest的一个功能吗?我需要minitest在assert_equal(42,ret)
失败后继续运行拆卸。它必须在报告中包含拆卸的故障/错误。