存储库未被模拟 JUnit5 [重复]

Repository is not being mocked JUnit5 [duplicate]

提问人:Natalia 提问时间:11/10/2023 最后编辑:Natalia 更新时间:11/11/2023 访问量:57

问:

运行单元测试时遇到以下错误: 错误:java.lang.NullPointerException:无法调用“com.example.gerenciadordetarefas.repository.task.TaskRepository.findById(Object)”,因为“this.taskRepository”为空

我知道存储库没有被嘲笑,但我不知道为什么。

TaskServiceTest(任务服务测试)

@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()通过?

java spring-boot nullpointerexception mockito junit5

评论

0赞 tgdavies 11/10/2023
当您创建一个新的 in 时,您正在替换其注入了模拟的实例。taskServicesetUpTaskService
0赞 tgdavies 11/10/2023
顺便说一句,我建议使用构造函数注入。这将使这个问题更加清晰。
0赞 Natalia 11/11/2023
即使删除了 service = new TaskService(userService),错误仍然存在。像这样在 TaskService 中实现依赖关系注入,因为我遇到了循环依赖关系错误。

答:

0赞 mirzak 11/10/2023 #1

您在这里遇到的问题是您正在覆盖已注入模拟的 TaskService。您可以在设置中创建它的新实例。

如果可能的话,你可以有这样的东西

@Mock
Repository repository;
@Mock
OtherService otherService;
TaskService service;

@Setup
void setup() {
    service = new TaskService(repository, otherService);
}

如果无法使用构造函数注入注入存储库,则可以执行之前执行的操作,但以注入存储库的相同方式注入其他服务。

第三个选项是通过任务服务中的 setter 设置其他服务,但我不建议这样做。

评论

0赞 tgdavies 11/10/2023
他们应该能够删除该行。我希望 Mockito 将同时进行现场和 ctor 注射。service = new TaskService(userService);
0赞 Natalia 11/11/2023
即使删除了 service = new TaskService(userService),错误仍然存在。
0赞 tgdavies 11/11/2023
完全相同的错误?
0赞 Natalia 11/11/2023
是的,同样的错误
0赞 Natalia 11/11/2023
我找出了导致错误的原因。由于构造函数中的@Autowired,@Autowired被忽略了,所以我重构了它,它看起来像这样:TaskService { private final TaskRepository taskRepository; private final UserService userService; @Autowired public TaskService(@Lazy UserService userService, TaskRepository taskRepository) { this.userService = userService; this.taskRepository = taskRepository; } }