Spock verifying an exception thrown by mock together with mock interaction

jarzeb picture jarzeb · Apr 30, 2015 · Viewed 14.3k times · Source

The problem I encountered is when I try to verify in the then block that an exception has been thrown, and that call on a mock has been made.

Look at the setup below:

class B {
    def b(A a) {
        a.a()
    }
}

class A {
    def a() {
    }
}

def "foo"() {
    given:
    def a = Mock(A)
    a.a() >> { throw new RuntimeException() }
    B b = new B()

    when:
    b.b(a)

    then:
    thrown(RuntimeException)
    1 * a.a()
}

The above test fails with message: Expected exception java.lang.RuntimeException, but no exception was thrown, but the code setting up the mock explicitly throws the exception.

Funny enough, if you remove the last line: 1 * a.a() the test passes. I didn't have similar problem when putting together another assertions in the then block which don't verify exceptions.

Any ideas what's going on?

Answer

Opal picture Opal · Apr 30, 2015

It should be configured and verified in the following way:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {
    def "foo"() {
        given:
        def a = Mock(A)
        B b = new B()

        when:
        b.b(a)

        then:
        thrown(RuntimeException)
        1 * a.a() >> { throw new RuntimeException() }
    }
}


class B {
    def b(A a) {
        a.a()
    }
}

class A {
    def a() {
    }
}

If you both mock and verify interactions mock behavior should be configured in where/then block.