Daniel Scott
Daniel Scott

Reputation: 7951

Chaining side effects from spock stub with void return type

I'm trying to test the following (contrived) code, which makes a call, and attempts one retry, if the call fails.

 public class MyObject
 {
    public void process(final Client client) throws IOException
    {
        try
        {
            client.send();
        }
        catch (IOException e)
        {
            client.fix();
        }

        try
        {
            client.send();
        }
        catch (IOException e)
        {
            throw new IOException(e);
        }
    }

    public class Client
    {
        public void send() throws IOException {}

        public void fix() {}
    }
}

My testing strategy is to mock the client object and stub a response that will throw an exception on the first call to send() and then succeed on the second attempt.

Using spock, I have the following:

def "test method calls"() {
   setup:
   def MyObject myObject = new MyObject()
   def Client client = Mock(Client)

   when:
   myObject.process(client)

   then:
   2 * client.send() >>> {throw new IOException()} >> void
}

I've tried the above, and replacing void with null, and keep getting cast exceptions.

I've also tried:

2 * client.send() >>> [{throw new MyException()}, void]

How can I mock my desired response?

Upvotes: 2

Views: 2696

Answers (2)

Works fine.

1*getName()>>"Hello"
1*getName()>>"Hello Java"

First Invocation im getting "Hello". Second Invocation im getting "Hello Java"

Upvotes: 0

Ben Green
Ben Green

Reputation: 4121

This test passes. I have added comments to show what each step indicates:

def "test method calls"() {
    given:
    def MyObject myObject = new MyObject()
    def MyObject.Client client = Mock(MyObject.Client)
    //The first time client.send() is called, throw an exception
    1 * client.send() >> {throw new IOException()}
    //The second time client.send() is called, do nothing. With the above, also defines that client.send() should be called a total of 2 times. 
    1 * client.send()
    when:
    myObject.process(client)
    then:
    noExceptionThrown() //Verifies that no exceptions are thrown
    1 * client.fix() // Verifies that client.fix() is called only once.
}

Upvotes: 4

Related Questions