为什么在使用方法计数时从模拟中抛出的异常消失了?

Why are exceptions thrown from mocks gone when using method count?

我正在使用 spock 单元测试测试一些 Java 代码。在一个测试用例中,我需要测试抛出异常时 class 是否正确运行。我模拟了抛出异常的调用,然后测试是否调用了该方法以及返回的结果是否正确。

我使用的代码相当冗长,所以我将其缩小到这个例子,这是一个有点毫无意义的测试,但仍然说明了问题:

def "test if an exception is thrown on a mock"() {
    given:
        Object o = Mock() {
            toString() >> {throw new UnsupportedOperationException("no message")}
        }
    when:
        o.toString()
    then:
        thrown(UnsupportedOperationException)
}

这很好用。异常从模拟中抛出并且测试运行绿色。但是,如果我添加一个方法调用计数器,则不再抛出异常。如果我将 then 块更改为

then:
    1 * o.toString()
    thrown(UnsupportedOperationException)

测试失败。我用调试器检查了一下,结果是 toString() 现在 returns null 而不是抛出异常。为什么会发生这种情况,我该如何解决?

你的案例在 spock 文档中有很好的解释。 请参考this section

为了快速修复,我建议

def "test if an exception is thrown on a mock"() {
    given:
        Object o = Mock() {
            // Stubbing and Mock-verifying at the same time
            1 * toString() >> {throw new UnsupportedOperationException("no message")}
        }
    when:
        o.toString()
    then:
        thrown(UnsupportedOperationException)
}