Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Spock Framework Mock


Spock Framework Mocks are powerful and very easy to use. Learn here how to use and interact with Mocks in your unit tests on these examples!


Common scenario: test a class that interacts with other classes, but don’t instantiate half of the system just for a unit test. In our example we want to test UserController, which could be a REST controller for Users. It receives data from a GUI and delegates to a UserService to perform actual work with the data. We know that UserService implementations work and we only want to test the controller.

So… let’s start with definitions of Java classes used in tests: User, UserService interface, and UserController.

First our domain object used in tests, User:

package com.farenda.solved;

public class User {

    private final String name;

    public User(String name) { = name;

    public String getName() {
        return name;

    public String toString() {
        return "User('" + name + "')";

Now the UserService interface that we will mock in tests:

package com.farenda.solved;

import java.util.Set;

public interface UserService {

     * Return true when user exists.
    boolean exists(User user);

     * Add a new user, but only if it doesn't exist yet.
     * @param user to add
    void add(User user);

     * Remove a user with given name.
     * @param name of user to remove
    void remove(String name);

     * Return all users.
     * @return All users or empty Set.
    Set<User> getAll();

Next, the REST Controller:

package com.farenda.solved;

public class UserController {

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;

    public void addUser(String name) {
        userService.add(new User(name));

We’ve got basic setup. Now it’s time to test the controller:

package com.farenda.solved

import spock.lang.Specification

class BasicMocksTest extends Specification {

    // Creating Mock is simple as that:
    def userService = Mock(UserService)

    // This will also work, but I prefer the former version:
    // def UserService anotherService = Mock()

    // In Groovy you can call setter like this:
    def restController = new UserController(userService: userService)

    def 'should not add existing users'() {
        // For any User passed as parameter return "true" from Mock
        // We don't specify how many times we expect it to be called,
        // because we don't care in this test:
        userService.exists(_ as User) >> true

        restController.addUser('Jon Snow')

        // "n * method()" means "expect _exactly_ n calls of method()"
        // Change 0 to some other value and see what is happens!
        0 * userService.add(_ as User)

Things to note here:

  1. Spock Mocks work only with interfaces by default. If you want to mock classes be sure to have cglib and org.objenesis on the classpath (see posts on Spock Framework config for Gradle and Maven).
  2. In calls to Mock there is _ as Type, which means “any object of type Type”. If you would pass an object here (instantiated User) then it would be compared using equals with values passed as parameter.
  3. method() >> value means “on call to method() return value”.
  4. If you want you can specify how many times method may be called. It can be a number or a range:
    method()             // any number of times
    0 * method()         // expect 0 invocations
    (1..3) * method()    // expect 1 to 3 calls
    (_..2) * method()    // expect at most 2 calls
    (1.._) * method()    // expect at least 1 call

    Flexible, isn’t it? :-)

  5. Mock methods are defined in given and then blocks. They can be defined in any place, and it’s just a matter of style. I put definitions that direct flow of execution in given block and calls that are expected results in then/expect blocks. This way I state my intentions clearly.

OK. When you run the above test you’ll see that it… fails! :-)

Spock Framework Mock Too many invocations

Spock Framework Mock Too many invocations

It’s on purpose. In test I stated that user should not be added when already exists, but the implementation always calls userService.add() method. Let’s fix that:

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

Now it works as expected! :-)

You’ve learned basics of Mocking in Spock Framework! In subsequent posts we’ll show more complex and interesting examples leveraging power of Spock and Groovy.

Share with the World!