【问题标题】:Mockito how to mock Optional.map().orElseThrow()Mockito 如何模拟 Optional.map().orElseThrow()
【发布时间】:2023-02-03 19:05:37
【问题描述】:

今天我遇到以下问题-
我正在上 Udemy 课程,我尝试测试以下方法:

public GroupReadModel createGroup(LocalDateTime deadline, Integer projectId) {
    if (!configurationProperties.getTemplate().isAllowMultipleTasks() && taskGroupRepository.existsByDoneIsFalseAndProject_Id(projectId)) {
        throw new IllegalStateException("Only one undone group form project is allowed");
    }

    TaskGroup result = projectRepository.findById(projectId)
            .map(project -> {
                TaskGroup taskGroup = new TaskGroup();
                taskGroup.setDescription(project.getDescription());
                taskGroup.setTasks(project.getProjectSteps().stream()
                        .map(step -> Task.createNewTask(step.getDescription(), deadline.plusDays(step.getDaysToDeadline())))
                        .collect(Collectors.toSet()));
                taskGroup.setProject(project);
                return taskGroupRepository.save(taskGroup);
            }).orElseThrow(() -> new NoSuchElementException(String.format("No project with ID %d found", projectId)));

    return new GroupReadModel(result);
}

下面是测试方法:

@ExtendWith(SpringExtension.class)
class ProjectServiceTest {

    @Autowired
    private ProjectService projectService;

    @MockBean
    private ProjectRepository projectRepository;
    @MockBean
    private TaskGroupRepository taskGroupRepository;
    @MockBean
    private TaskConfigurationProperties configurationProperties;
    @Mock
    private TaskConfigurationProperties.Template template;

    @TestConfiguration
    static class ProjectServiceTestConfig {
        @Bean
        ProjectService projectService(ProjectRepository projectRepository, TaskGroupRepository taskGroupRepository, TaskConfigurationProperties configurationProperties ){
            return new ProjectService(projectRepository, taskGroupRepository, configurationProperties);
        }
    }


    @Test
    void should_return_new_group_read_model() {
        //given
        LocalDateTime deadline = LocalDateTime.now();
        Integer projectId = 99;
        Project projectById = new Project(projectId, "test project");
        projectById.setProjectSteps(Set.of(new ProjectStep("test1", 2)));
        TaskGroup taskGroupSaved = TaskGroup.CreateNewTaskGroup(projectById.getDescription(), Set.of(Task.createNewTask("test1", LocalDateTime.now())));
        GroupReadModel expectedResult = new GroupReadModel(taskGroupSaved);
        expectedResult.setDeadline(expectedResult.getDeadline().plusDays(2));
        Mockito.when(configurationProperties.getTemplate()).thenReturn(template);
        Mockito.when(template.isAllowMultipleTasks()).thenReturn(true);
        Mockito.when(taskGroupRepository.existsByDoneIsFalseAndProject_Id(projectId)).thenReturn(false);
        Mockito.when(projectRepository.findById(projectId)).thenReturn(Optional.of(projectById));

        //when
        GroupReadModel result = projectService.createGroup(deadline, projectId);

        //then
        assertEquals(expectedResult, result);
    }

我的问题是

Mockito.when(projectRepository.findById(projectId)).thenReturn(Optional.of(projectById));

结果 java.util.NoSuchElementException:找不到 ID 为 99 的项目
就像它从未被嘲笑过一样。对我来说有趣的是,这将适用于以下情况:

Project projectById = projectRepository.findById(projectId)
        .orElseThrow(() -> new NoSuchElementException(String.format("No project with ID %d found", projectId)));
TaskGroup taskGroup = new TaskGroup();
taskGroup.setDescription(projectById.getDescription());
taskGroup.setTasks(projectById.getProjectSteps().stream()
        .map(step -> Task.createNewTask(step.getDescription(), deadline.plusDays(step.getDaysToDeadline())))
        .collect(Collectors.toSet()));
taskGroup.setProject(projectById);
taskGroupRepository.save(taskGroup);

如您所见,首先我从存储库中获取我的对象,然后进行其余逻辑。但是我想知道我做错了什么所以它不适用于映射

MapResult result = projectRepository.findById(projectId)
    .map(some_logic)
    .orElseThrow(some_exception)

请告知我做错了什么,我该如何纠正?

【问题讨论】:

    标签: spring testing mockito


    【解决方案1】:

    您从 .map() 调用返回了 null,因此您陷入了 orElseThrow()。

    null来自return taskGroupRepository.save(taskGroup);

    存储库是模拟的,save 未存根,因此返回 null。

    最重要的是: @SpringBootTest 对您的测试来说可能有点矫枉过正。 @MockitoExtension、@Mock 和@InjectMocks 应该足够了。

    【讨论】:

      猜你喜欢
      • 2021-08-15
      • 1970-01-01
      • 2021-11-07
      • 2018-10-08
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多