I'm testing error handling. I want the first call to mockedObject.foo()
to throw a new IOException, and the second to return bar. I tried the following code,
mockedObject.foo() >>> [{throw new IOException()}, bar]
But, when I run the test, I get an error stating that a closure cannot be cast to Bar,
FooSpec$_$spock_feature_0_1_closure2 cannot be cast to Bar
How can I mock this behavior with Spock?
EDIT: After seeing the documentation referenced by tim_yates, I just changed the test to,
mockedObject.foo() >>> firstBar >> {throw new IOException()} >> secondBar
This comes close enough to testing what I needed to test. The following code threw the same exception, so I'm guessing Spock is setting the return type of the mocked method based on the first object return.
mockedObject.foo() >>> {throw new IOException()} >> secondBar
Here, a complete working example:
@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib:3.1')
@Grab('org.ow2.asm:asm-all:5.0.3')
import spock.lang.*
class MyTestSpec extends Specification {
def 'spec'() {
given:
def a = new A()
a.b = Mock(B) {
foob() >> { throw new Exception('aaa') } >> 1
}
when:
a.fooa()
then:
def e = thrown(Exception)
e.message == 'aaa'
when:
def r = a.fooa()
then:
r == 1
}
}
class A {
B b = new B()
Integer fooa() {
b.foob()
}
}
class B {
Integer foob() {
2
}
}