Warning: Use of undefined constant fixed - assumed 'fixed' (this will throw an Error in a future version of PHP) in /home/webtro13/domains/farenda.com/public_html/wp-content/themes/moments/header.php on line 65
class="header_container_flat">

Java Programming Tutorials

Java programming tutorials with many code examples!

Spock Framework Mock throw exception

Spock Framework Mocks allow to easily test handling of unexpected behaviors and inspect thrown exceptions. See how to *throw and handle expected exceptions in unit tests!

System under test

Here’s a part of our system that we want to examine. It consists of only two parts: UserController and UserService.

You can imagine that UserService implementation will do some logic of adding a user somewhere:

package com.farenda.tutorials.spock;

public interface UserService {

    boolean exists(User user);

    void add(User user);
}

The REST Controller just takes incoming objects and interacts with the service:

package com.farenda.tutorials.spock;

//@RestController and other annotations removed for brevity
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    public void addUser(String name) {
        if (!userService.exists(name)) {
            userService.add(new User(name));
        }
    }
}

Testing exception handling

Sometimes there’s a need to test handling of exceptions in code and we would like to throw them from Mock. This example shows how to do that:

package com.farenda.tutorials.spock

import spock.lang.Specification

class MockThrowExceptionTest extends Specification {

    // an interface with two methods: exists(user), add(user)
    def userService = Mock(UserService)

    // a controller to test, that will use mock of the service:
    def controller = new UserController(userService)

    def 'should throw exception for invalid username'() {
        given:
        def username = 'Joffrey Baratheon'
        userService.exists(_ as User) >> false
        userService.add(_ as User) >> { User user ->
            throw new IllegalArgumentException(user.name)
        }

        when:
        controller.addUser(username)

        then:
        def e = thrown(IllegalArgumentException)
        e.message == username
    }
}

In the example, the return value for exists() method could have been omitted, because the default value is false anyway.

The important point here is that we throw an exception from Groovy closure and expect it using Spock’s thrown(Type) method. A nice thing is that we can assign the exception to a variable and assert its data.

When exception is not thrown

When the exception is not thrown, then Spock will print the following error:

Expected exception of type 'java.lang.IllegalArgumentException', but no exception was thrown
      at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
      at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
      at com.farenda.solved.MockThrowExceptionTest.should throw exception for invalid username(MockThrowExceptionTest.groovy:26)

Expect no exceptions to be thrown

Of course there is also complementary method that allows to assert that an exception has not been thrown:

def 'should not throw'() {
  when:
  controller.addUser(null)

  then:
  notThrown(IllegalArgumentException)
  // other assertions
}

Now, you’ve got another tool in your Spock testing toolbox! :-)

Share with the World!