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
相关产品推荐
相关产品推荐

