Contents

Create a unit test with mocks using Java

Writen by: David Vlijmincx

Introduction

This post builds further on this earlier post where we added testing to a Java project. In this tutorial, we are going to create a test and mock a dependency the production code uses with Mockito as our mocking library.

The code we want to test

To show you how to create a mock inside a unit test we need to have some code we can test. For the examples in this post, I am going to use the following example of the Car and Engine class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Car.java
public class Car {

    private final Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public String MakeSound() {

        if (engine.start()) {
            return "Vrooommm!";
        } else {
            return "Not starting...";
        }

    }

}


// Engine.java
class Engine {

    public boolean start() {
        return true;
    }
}

The Car class has a dependency on the Engine class. The Car uses the Engine class inside the makeSound() method. If the engine starts we get a sound, if not we get a string saying the engine could not start. We are going to mock the Engine class so the start method returns false when we want to.

The testing code

In the following example, I created two test cases. In the first example, the engine starts and returns true, and in the second example the engine fails to start and returns false. The mocking of the Engine class is done on line 13 in the first example and on line 28 in the second example. On those lines, the mock is created, and we can change the behavior of those mocks. I change the behavior on line 14 and 29. With the when method, I can pass a method that I want to stub. For the first test I want to return true and for the second test, I want to return false.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class CarTest {

    @Test
    void MakeSound_EngineStarts() {

        //given
        Engine mockEngine = mock(Engine.class);
        when(mockEngine.start()).thenReturn(true);
        Car car = new Car(mockEngine);

        // when
        String result = car.MakeSound();

        //then
        assertEquals("Vrooommm!", result);
    }

    @Test
    void MakeSound_EngineDoesNotStarts() {

        //given
        Engine mockEngine = mock(Engine.class);
        when(mockEngine.start()).thenReturn(false);
        Car car = new Car(mockEngine);

        // when
        String result = car.MakeSound();

        //then
        assertEquals("Not starting...", result);
    }
}

Throughout the tests only the mockEngine is used and not a real instance of the Engine class. When I create a Car I pass the mock and not a newly created engine instance. This is very important as the Car instance has to use the mocks for the tests to succeed.

Conclusion

This post covered how to create mock instances inside unit tests. This makes testing different branches inside your code a lot easier as you can influence the behavior of the dependencies of a class.