Search code examples
javaunit-testingexceptionmockingspock

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


I am testing some Java code using spock unit tests. In one test case I need to test if a class behaves correctly when an exception is thrown. I mocked the call to throw an exception and then I test if the method is called and if the returned result is correct.

The code I'm using is rather lengthy so I narrowed it down to this example which is a somewhat pointless test but still illustrates the problem:

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)
}

This works fine. The exception is thrown from the mock and the test runs green. However if I add a method call counter the exception is not thrown anymore. If I change the then block to

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

the test fails. I checked with a debugger and it turns out that toString() now returns null instead of throwing an exception. Why does this happen and what can I do to fix it?


Solution

  • Your case is well explained in spock document. Please refer to this section

    For a quick fix, I suggest

    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)
    }