📌 Why Unit Testing?
✅ Ensures that business logic works as expected.
✅ Detects issues early before integration testing.
✅ Isolates service logic from the database and controllers.
✅ Provides fast feedback compared to full integration tests.
🚀 Step 1: Add Required Dependencies
📌 Ensure the following dependencies are present in pom.xml
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
📌 Explanation
✔️ Mockito → Used for mocking dependencies (database, services).
🚀 Step 2: Mock Dependencies in the Service Layer
Since we don't want to interact with the actual database, we will mock the repository and test the service logic independently.
📌 Create UserServiceTest.java
inside net.javaguides.usermanagement.service
package net.javaguides.usermanagement.service;
import net.javaguides.usermanagement.dto.UserDto;
import net.javaguides.usermanagement.entity.User;
import net.javaguides.usermanagement.exception.ResourceNotFoundException;
import net.javaguides.usermanagement.mapper.UserMapper;
import net.javaguides.usermanagement.repository.UserRepository;
import net.javaguides.usermanagement.service.impl.UserServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.*;
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Mock
private UserMapper userMapper;
@InjectMocks
private UserServiceImpl userService;
private User user;
private UserDto userDto;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
// Initialize test data
user = new User();
user.setId(1L);
user.setFirstName("Ravi");
user.setLastName("Kumar");
user.setEmail("ravi.kumar@example.com");
user.setDateOfBirth(LocalDate.of(1995, 8, 15));
userDto = new UserDto(
1L,
"Ravi",
"Kumar",
"ravi.kumar@example.com",
LocalDate.of(1995, 8, 15)
);
}
}
📌 Explanation
✔️ @Mock
→ Mocks UserRepository
and UserMapper
so that we don’t interact with the real database.
✔️ @InjectMocks
→ Injects mocked dependencies into UserServiceImpl
.
✔️ @BeforeEach
→ Runs before each test to initialize test data.
🚀 Step 3: Write Unit Test for createUser
Method
📌 Add the following test inside UserServiceTest.java
@Test
void shouldCreateUser() {
// Arrange
when(userMapper.toEntity(userDto)).thenReturn(user);
when(userRepository.save(user)).thenReturn(user);
when(userMapper.toDto(user)).thenReturn(userDto);
// Act
UserDto createdUser = userService.createUser(userDto);
// Assert
assertThat(createdUser).isNotNull();
assertThat(createdUser.id()).isEqualTo(1L);
assertThat(createdUser.email()).isEqualTo("ravi.kumar@example.com");
verify(userRepository, times(1)).save(user);
}
📌 Explanation
✔️ Mocks the save
method to return the test user.
✔️ Verifies that save()
was called exactly once.
✔️ Asserts that the returned user matches expected values.
🚀 Step 4: Write Unit Test for getUserById
Method
📌 Add the following test inside UserServiceTest.java
@Test
void shouldGetUserById() {
// Arrange
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
when(userMapper.toDto(user)).thenReturn(userDto);
// Act
UserDto retrievedUser = userService.getUserById(1L);
// Assert
assertThat(retrievedUser).isNotNull();
assertThat(retrievedUser.id()).isEqualTo(1L);
verify(userRepository, times(1)).findById(1L);
}
📌 Explanation
✔️ Mocks findById(1L)
to return test user.
✔️ Asserts that the returned user is not null.
🚀 Step 5: Write Unit Test for Exception Handling
📌 Add the following test inside UserServiceTest.java
@Test
void shouldThrowExceptionWhenUserNotFound() {
// Arrange
when(userRepository.findById(1L)).thenReturn(Optional.empty());
// Act & Assert
assertThatThrownBy(() -> userService.getUserById(1L))
.isInstanceOf(ResourceNotFoundException.class)
.hasMessage("User not found with id: 1");
verify(userRepository, times(1)).findById(1L);
}
📌 Explanation
✔️ Mocks findById(1L)
to return empty (user does not exist).
✔️ Asserts that an exception is thrown when the user is not found.
🚀 Step 6: Write Unit Test for getAllUsers
Method
📌 Add the following test inside UserServiceTest.java
@Test
void shouldGetAllUsers() {
// Arrange
when(userRepository.findAll()).thenReturn(Arrays.asList(user));
when(userMapper.toDto(user)).thenReturn(userDto);
// Act
List<UserDto> users = userService.getAllUsers();
// Assert
assertThat(users).hasSize(1);
verify(userRepository, times(1)).findAll();
}
🚀 Step 7: Write Unit Test for updateUser
Method
📌 Add the following test inside UserServiceTest.java
@Test
void shouldUpdateUser() {
// Arrange
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
when(userRepository.save(user)).thenReturn(user);
when(userMapper.toDto(user)).thenReturn(userDto);
// Act
UserDto updatedUser = userService.updateUser(1L, userDto);
// Assert
assertThat(updatedUser).isNotNull();
verify(userRepository, times(1)).save(user);
}
🚀 Step 8: Write Unit Test for deleteUser
Method
📌 Add the following test inside UserServiceTest.java
@Test
void shouldDeleteUser() {
// Arrange
when(userRepository.existsById(1L)).thenReturn(true);
// Act
userService.deleteUser(1L);
// Assert
verify(userRepository, times(1)).deleteById(1L);
}
🚀 Running the Tests
📌 Execute all the JUnit test cases by running the UserServiceTest class.
✅ All tests should pass successfully.
🎯 Summary: What We Achieved
✔️ Mocked dependencies using Mockito.
✔️ Wrote unit tests for all service methods.
✔️ Tested exception handling scenarios.
✔️ Ensured CRUD operations work correctly.
🚀 Now your Spring Boot Service Layer is fully tested with JUnit 5 & Mockito! 🎯
Comments
Post a Comment
Leave Comment