mockito 模拟如何模拟Optional.map().或ElseThrow()

ldfqzlk8  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(189)

今天我遇到了以下问题-
我正在做一个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.无此类元素异常:未找到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);

正如您所看到的,首先我从存储库中获取对象,然后执行其余的逻辑,但是我想知道我做错了什么,所以它不能与Map一起工作

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

请告诉我做错了什么,我该如何改正?

tvmytwxo

tvmytwxo1#

您从.map()调用返回了null,因此您陷入了orElseThrow()。
空值来自return taskGroupRepository.save(taskGroup);
存储库是模拟的,save没有存根,因此返回null。
在顶部,如果:
"你不必嘲笑一切"
如果您的任何对象是POJO,请使用所需的状态而不是mock来构造它们。

简化测试设置

@SpringBootTest对于您的测试来说可能是矫枉过正,@MockitoExtension、@Mock和@InjectMocks应该足够了。

相关问题