Search code examples
spock

How can I create a spock mock that evaluates a closure at every call?


I have a method which returns an InputStream and a test case in which I have to mock that method:

def myMock = Mock(MyClass) {
    get(InputStream) >> new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))
}

The problem is that this method is called more than once which means that the second time the input stream is already closed and empty. So I used a list instead which i filled beforehand with multiple instances of the input stream like this:

def myMock = Mock(MyClass) {
    get(InputStream) >>> ([ByteArrayInputStream] * numCalls)*.newInstance("bla bla".getBytes(Charset.defaultCharset()))
}

which works if I know the number of calls to that method before the execution. But I think it would be more elegant to have a closure which is evaluated every time the method is called. I followed this answer and tried to do it this way:

def myMock = Mock(MyClass) {
    get(InputStream) >>> [].withDefault{
        new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))
    }
}

But that causes the get method to always return null. Is there a way to solve this?


Solution

  • OK, turns out I was overthinking. I solved like this:

    def myMock = Mock(MyClass) {
        get(InputStream) >> {new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))}
    }
    

    So just wrap the constructor in a closure and use the >> operator, not the >>> operator and it works like a charm.