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

JUnit5测试中TaskRepository未Mock致空指针,如何通过createTask测试?

解决TaskService.createTask()测试空指针问题

核心问题分析

出现NullPointerException是因为TaskService中的taskRepository字段未被正确注入Mock实例,导致调用其方法时触发空指针。以下是具体修复步骤:

修复步骤

1. 配置测试类启用Mockito

如果使用JUnit 5,在测试类上添加@ExtendWith(MockitoExtension.class);若用JUnit 4,则添加@RunWith(MockitoJUnitRunner.class),让Mockito能自动管理Mock实例的注入。

2. 正确Mock依赖并注入到TaskService

  • 对TaskRepository和TaskService依赖的其他服务(比如UserService)添加@Mock注解,创建Mock实例
  • 对TaskService添加@InjectMocks注解,让Mockito自动将Mock依赖注入到Service中

示例测试代码:

// JUnit 5 示例
@ExtendWith(MockitoExtension.class)
class TaskServiceTest {
    @Mock
    private TaskRepository taskRepository;
    
    @Mock
    private UserService userService;
    
    @InjectMocks
    private TaskService taskService;
    
    @Test
    void createTask_ShouldReturnSavedTask() {
        // 模拟依赖行为
        User mockUser = new User(1L, "test@example.com");
        TaskRequest request = new TaskRequest("新建任务", "任务描述", 1L);
        Task savedTask = new Task(1L, request.getTitle(), request.getDescription(), mockUser);
        
        when(userService.findById(1L)).thenReturn(Optional.of(mockUser));
        when(taskRepository.save(any(Task.class))).thenReturn(savedTask);
        
        // 执行测试方法
        Task result = taskService.createTask(request);
        
        // 断言结果
        assertEquals(savedTask.getTitle(), result.getTitle());
        verify(taskRepository, times(1)).save(any(Task.class));
    }
}

3. 确保TaskService的依赖注入方式正确

优先使用构造函数注入,这种方式不仅符合Spring最佳实践,也能让Mockito顺利注入Mock实例:

@Service
public class TaskService {
    private final TaskRepository taskRepository;
    private final UserService userService;
    
    // 构造函数注入依赖
    public TaskService(TaskRepository taskRepository, UserService userService) {
        this.taskRepository = taskRepository;
        this.userService = userService;
    }
    
    public Task createTask(TaskRequest request) {
        User user = userService.findById(request.getUserId())
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        Task task = new Task(null, request.getTitle(), request.getDescription(), user);
        return taskRepository.save(task);
    }
}

4. 禁止手动实例化TaskService

如果测试中用new TaskService()手动创建实例但未传入Mock的taskRepository,必然会导致空指针。必须通过@InjectMocks让Mockito注入依赖,或者手动传入Mock实例:

// 手动注入的替代方式(不推荐,不如@InjectMocks便捷)
class TaskServiceTest {
    private TaskRepository taskRepository = mock(TaskRepository.class);
    private UserService userService = mock(UserService.class);
    private TaskService taskService = new TaskService(taskRepository, userService);
    
    // ...测试用例
}

关键检查项

  • 测试类是否启用了Mockito扩展/运行器
  • @Mock和@InjectMocks注解是否正确添加到对应字段
  • TaskService的依赖是否通过构造函数或可注入的方式声明
  • 未手动创建Service实例却忽略依赖传递

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:16:08