请求协助编写UserServiceImpl中updateUser与getUsers的JUnit测试用例
JUnit测试用例编写方案(针对UserServiceImpl的两个方法)
你的testUpdateUser测试失败,核心原因是没有模拟userRepository.findByUserId的返回值——调用updateUser时,userRepository.findByUserId("edsd3445tcd")会返回null,触发UsernameNotFoundException,导致测试提前终止。
以下是覆盖两个方法所有业务分支的完整JUnit测试用例(基于Mockito和JUnit 5):
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class UserServiceImplTest { @Mock private UserRepository userRepository; // 替换为你实际的Repository接口类 @InjectMocks private UserServiceImpl userService; // 要测试的业务实现类 // --- updateUser 测试用例 --- // 场景1:用户存在时,成功更新并返回转换后的UserDto @Test void updateUser_WhenUserExists_ReturnsUpdatedUserDto() { // 1. 准备测试数据 String userId = "edsd3445tcd"; // 模拟数据库中已存在的用户实体 UserEntity existingUser = new UserEntity(); existingUser.setUserId(userId); existingUser.setName("旧用户名"); existingUser.setCity("旧城市"); // 准备要更新的用户数据 UserDto updateDto = new UserDto(); updateDto.setName("新用户名"); updateDto.setCity("新城市"); updateDto.setAddress("新地址"); updateDto.setPhoneNumber("13800138000"); // 模拟更新后持久化的实体 UserEntity updatedUser = new UserEntity(); updatedUser.setUserId(userId); updatedUser.setName(updateDto.getName()); updatedUser.setCity(updateDto.getCity()); updatedUser.setAddress(updateDto.getAddress()); updatedUser.setPhoneNumber(updateDto.getPhoneNumber()); // 2. 模拟Repository方法行为 when(userRepository.findByUserId(eq(userId))).thenReturn(existingUser); when(userRepository.save(any(UserEntity.class))).thenReturn(updatedUser); // 3. 执行测试方法 UserDto result = userService.updateUser(userId, updateDto); // 4. 断言结果 assertNotNull(result); assertEquals(updateDto.getName(), result.getName()); assertEquals(updateDto.getCity(), result.getCity()); assertEquals(updateDto.getAddress(), result.getAddress()); assertEquals(updateDto.getPhoneNumber(), result.getPhoneNumber()); } // 场景2:用户不存在时,抛出指定异常 @Test void updateUser_WhenUserNotFound_ThrowsUsernameNotFoundException() { // 1. 准备测试数据 String invalidUserId = "non-existent-id"; UserDto updateDto = new UserDto(); // 2. 模拟Repository返回null(用户不存在) when(userRepository.findByUserId(eq(invalidUserId))).thenReturn(null); // 3. 执行并断言异常 UsernameNotFoundException exception = assertThrows(UsernameNotFoundException.class, () -> userService.updateUser(invalidUserId, updateDto)); assertEquals("User with ID: " + invalidUserId + " not found", exception.getMessage()); } // --- getUsers 测试用例 --- // 场景1:分页查询有数据时,返回转换后的UserDto列表 @Test void getUsers_WhenPageHasData_ReturnsUserDtoList() { // 1. 准备测试数据 int page = 0; int limit = 2; // 模拟数据库中的用户实体列表 List<UserEntity> userEntities = new ArrayList<>(); UserEntity user1 = new UserEntity(); user1.setUserId("user-001"); user1.setName("用户A"); user1.setCity("北京"); UserEntity user2 = new UserEntity(); user2.setUserId("user-002"); user2.setName("用户B"); user2.setCity("上海"); userEntities.add(user1); userEntities.add(user2); // 模拟分页查询的Page对象 Pageable pageable = PageRequest.of(page, limit); Page<UserEntity> userPage = new PageImpl<>(userEntities, pageable, userEntities.size()); // 2. 模拟Repository方法行为 when(userRepository.findAll(eq(pageable))).thenReturn(userPage); // 3. 执行测试方法 List<UserDto> result = userService.getUsers(page, limit); // 4. 断言结果 assertNotNull(result); assertEquals(2, result.size()); assertEquals(user1.getName(), result.get(0).getName()); assertEquals(user2.getCity(), result.get(1).getCity()); } // 场景2:分页查询为空时,返回空列表 @Test void getUsers_WhenPageIsEmpty_ReturnsEmptyList() { // 1. 准备测试数据 int page = 0; int limit = 2; Pageable pageable = PageRequest.of(page, limit); Page<UserEntity> emptyPage = new PageImpl<>(new ArrayList<>(), pageable, 0); // 2. 模拟Repository返回空Page when(userRepository.findAll(eq(pageable))).thenReturn(emptyPage); // 3. 执行测试方法 List<UserDto> result = userService.getUsers(page, limit); // 4. 断言结果 assertNotNull(result); assertTrue(result.isEmpty()); } }
关键说明
- 依赖模拟:用
@Mock模拟Repository接口,避免连接真实数据库,专注测试业务逻辑;@InjectMocks自动将模拟的Repository注入到Service中。 - 分支覆盖:每个方法都覆盖了正常流程和异常/边界流程,确保业务逻辑的完整性。
- 测试流程:所有测试遵循「准备数据→模拟依赖行为→执行测试方法→断言结果」的标准流程,逻辑清晰易维护。
内容的提问来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

