我在运行单元测试时遇到以下错误: 错误:java.lang.NullPointerException:无法调用“com.example.gerenciadordetarefas.repository.task.TaskRepository.findById(Object)”,因为“this.taskRepository”为空 我知道存储库没有被嘲笑,但我不知道为什么。
任务服务测试
@ExtendWith(MockitoExtension.class)
class TaskServiceTest {
@Mock
private TaskRepository repository;
@InjectMocks
private TaskService service;
@Mock
private UserService userService;
private static final String TASK_ID_1 = "652d960af866034b686cca97";
private static final String TASK_ID_2 = "252d960af866034b686cca92";
private static final String USER_ID_1 = "642f6ab6813d692cef4795cc";
private final User user1 = User.builder()
.id(USER_ID_1)
.name("Maria Silva")
.assignedTasks(new ArrayList<>())
.build();
private final Task task = Task.builder()
.title("teste")
.description("teste aqui")
.dateOfCreation(LocalDate.now())
.dueDate(LocalDate.now())
.assigne(Collections.singletonList(user1))
.build();
private final TaskDto taskD = TaskDto.builder()
.title("teste")
.description("teste aqui")
.dateOfCreation(LocalDate.now())
.dueDate(LocalDate.now())
.assigne(Collections.singletonList(USER_ID_1))
.build();
@BeforeEach
void setUp() {
// MockitoAnnotations.initMocks(this);
service = new TaskService(userService);
Mockito.lenient().when(userService.getUserById(USER_ID_1)).thenReturn(user1);
Mockito.lenient().when(repository.save(Mockito.any(Task.class))).thenReturn(task);
Mockito.lenient().when(repository.findById(TASK_ID_1)).thenReturn(Optional.of(task));
}
@Test
@DisplayName("Verificar se o objeto Task está sendo criado ")
void createTask() {
service.createTask(taskD);
verify(repository, times(1)).save(task);
}
任务服务:
@Service
public class TaskService {
@Autowired
private TaskRepository taskRepository;
private final UserService userService;
@Autowired
public TaskService(@Lazy UserService userService) {
this.userService = userService;
}
public TaskDtoResponse createTask(TaskDto taskDto) {
Task task = TaskMapper.taskDtoToTask(taskDto);
this.addToAssigne(taskDto, task);
taskRepository.save(task);
return TaskMapper.taskToTaskDtoResponse(task);
}
public Task addToAssigne(TaskDto taskDto, Task task){
List<String>assigne = taskDto.getAssigne();
assigne.forEach(id -> {
User user = userService.getUserById(id);
task.getAssigne().add(user);
});
return task;
}
}
任务存储库:
@Repository
public interface TaskRepository extends MongoRepository<Task, String> {
@Query("{_id: {$in:?0}})")
List<Task> findByIds(List<String> ids);
}
用户服务:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private TaskService taskService;
public UserDtoResponse createUser(UserDto userDto) {
User user = UserMapper.userDtoToUser(userDto);
if(userDto.getAssignedTasks() != null){
this.addToTaskList(userDto, user);
}
userRepository.save(user);
return UserMapper.userToUserDtoResponse(user);
}
public User addToTaskList(UserDto userDto, User user){
List<String>assignedTasks = userDto.getAssignedTasks();
assignedTasks.forEach(id-> {
Task task = taskService.getTaskById(id);
user.getAssignedTasks().add(task);
});
return user;
}
}
怎样才能让测试createTask()通过?
您遇到的问题是您正在重写已注入模拟的 TaskService。您可以在设置中创建它的新实例。
如果可以的话你可以拥有这样的东西
@Mock
Repository repository;
@Mock
OtherService otherService;
TaskService service;
@Setup
void setup() {
service = new TaskService(repository, otherService);
}
如果您无法使用构造函数注入来注入存储库,那么您可以执行之前所做的操作,但以注入存储库的方式注入其他服务。
第三个选项是通过任务服务中的 setter 设置其他服务,但我不建议这样做。