You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求协助编写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());
    }
}

关键说明

  1. 依赖模拟:用@Mock模拟Repository接口,避免连接真实数据库,专注测试业务逻辑;@InjectMocks自动将模拟的Repository注入到Service中。
  2. 分支覆盖:每个方法都覆盖了正常流程和异常/边界流程,确保业务逻辑的完整性。
  3. 测试流程:所有测试遵循「准备数据→模拟依赖行为→执行测试方法→断言结果」的标准流程,逻辑清晰易维护。

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:45:51