Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can you provide an example of using Mockito to mock a service in a JUnit 5 test


Can you provide an example of using Mockito to mock a service in a JUnit 5 test


Here's a detailed example of using Mockito to mock a service in a JUnit 5 test. This example involves a simple service that depends on another service, which we will mock.

Example Overview

Let's say we have a `UserService` that depends on a `UserRepository`. We want to test `UserService` without actually using the `UserRepository`, so we'll mock it.

Classes Involved

UserRepository Interface**

java
public interface UserRepository {
    User getUser(int id);
}

User Class**

java
public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

UserService Class**

java
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public String getUserName(int id) {
        User user = userRepository.getUser(id);
        if (user != null) {
            return user.getName();
        } else {
            return "User not found";
        }
    }
}

JUnit 5 Test with Mockito

To test `UserService`, we'll create a mock for `UserRepository` using Mockito. Here's how you can do it:

Using `@Mock` Annotation with `@ExtendWith(MockitoExtension.class)`**

This method is more concise and doesn't require manual initialization of mocks.

java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

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

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @Test
    void testGetUserName() {
        // Arrange
        int userId = 1;
        String expectedUserName = "John Doe";
        when(userRepository.getUser(userId)).thenReturn(new User(userId, expectedUserName));

        UserService userService = new UserService(userRepository);

        // Act
        String actualUserName = userService.getUserName(userId);

        // Assert
        assertEquals(expectedUserName, actualUserName);
    }
}

Using `Mockito.mock()` Method**

This method is useful when you don't want to use annotations or when working with older versions of JUnit.

java
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

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

public class UserServiceTest {

    @Test
    void testGetUserName() {
        // Arrange
        int userId = 1;
        String expectedUserName = "John Doe";
        UserRepository userRepository = Mockito.mock(UserRepository.class);
        when(userRepository.getUser(userId)).thenReturn(new User(userId, expectedUserName));

        UserService userService = new UserService(userRepository);

        // Act
        String actualUserName = userService.getUserName(userId);

        // Assert
        assertEquals(expectedUserName, actualUserName);
    }
}

Explanation

1. Mock Creation:
- In the first example, we use the `@Mock` annotation to create a mock of `UserRepository`. This requires `@ExtendWith(MockitoExtension.class)` to automatically initialize the mocks.
- In the second example, we use `Mockito.mock(UserRepository.class)` to manually create the mock.

2. Stubbing Behavior:
- We use `when(userRepository.getUser(userId)).thenReturn(new User(userId, expectedUserName));` to define the behavior of the mock. This means when `getUser` is called with `userId`, it will return a `User` object with the specified name.

3. Testing the Service:
- We create an instance of `UserService` with the mock `UserRepository`.
- We call the method under test (`getUserName`) and assert that the result matches our expectations.

This approach allows you to isolate the unit being tested (`UserService`) from its dependencies (`UserRepository`), making your tests more reliable and efficient.

Citations:
[1] https://www.digitalocean.com/community/tutorials/mockito-tutorial
[2] https://semaphore.io/community/tutorials/stubbing-and-mocking-with-mockito-2-and-junit
[3] https://reflectoring.io/clean-unit-tests-with-mockito/
[4] https://www.vogella.com/tutorials/Mockito/article.html
[5] https://www.digitalocean.com/community/tutorials/mockito-mock-examples
[6] https://stackoverflow.com/questions/71257469/initialise-a-service-for-mocking-in-java-with-mockito-and-junit-5
[7] https://www.lambdatest.com/blog/junit5-mockito-tutorial/
[8] https://springframework.guru/mocking-unit-tests-mockito/