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/