Search code examples
groovyspock

Throw IOException in multiple return results with Spock


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

Solution

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