Mockito @RunWith Example

1. Introduction

When writing tests in Mockito, we often use annotations like @Mock, @InjectMocks, @Spy, and @Captor to simplify the mock creation process. But for these annotations to be effective, they must be initialized. One of the ways to automatically initialize these annotations is by using the @RunWith(MockitoJUnitRunner.class) annotation. This ensures that all the Mockito annotations are initialized, which means we don't have to manually call MockitoAnnotations.initMocks(this).

2. Example Steps

1. Define an interface and its implementation.

2. Define a service class that uses the interface.

3. Create a test class.

4. Within the test class, annotate it with @RunWith(MockitoJUnitRunner.class).

5. Use Mockito annotations like @Mock and @InjectMocks within the test class.

6. Write the test methods.

7. Run the tests.

3. Mockito @RunWith Example

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

interface Calculator {
    int add(int a, int b);
}

class SimpleCalculator implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class CalculatorTest {

    @Mock
    Calculator mockCalculator;

    @InjectMocks
    SimpleCalculator simpleCalculator;

    @Test
    public void testAddition() {
        // Mock the add method of mockCalculator
        when(mockCalculator.add(10, 20)).thenReturn(30);

        // Call the add method
        int result = simpleCalculator.add(10, 20);

        // Assert the result
        assertEquals(30, result);
    }
}

Output:

The test will pass, ensuring that the mocked add method of the Calculator interface is used within the SimpleCalculator implementation.

4. Step By Step Explanation

1. We define an interface Calculator and a simple implementation of SimpleCalculator.

2. We then have a CalculatorTest class annotated with @RunWith(MockitoJUnitRunner.class). This ensures that all Mockito annotations inside this class are initialized without the need to explicitly call MockitoAnnotations.initMocks(this).

3. Inside the test class, we declare a mock for the Calculator interface using the @Mock annotation.

4. We also use the @InjectMocks annotation for the SimpleCalculator, which will use the mocked Calculator.

5. In the testAddition method, we mock the add method of mockCalculator to always return 30 when called with 10 and 20.

6. We then call the add method of our simpleCalculator and assert the result.

7. Thanks to the @RunWith(MockitoJUnitRunner.class) annotation, the initialization of the mock and the injection into simpleCalculator happen automatically, making our test setup cleaner and more efficient.


Comments