Spring Mockito:使用存储库模拟的特定参数调用方法时返回空值

问题描述 投票:0回答:1

我尝试模拟以下存储库并根据所有者的名称返回一页待办事项条目。我正在使用“org.springframework.boot”版本“3.1.3”。

@Repository
public interface NotioRepository extends CrudRepository<ToDo, Long>, PagingAndSortingRepository<ToDo, Long> {
    Page<ToDo> findByOwner(String owner, Pageable pageable);
    ...
}

我的控制器看起来像这样:

@RestController
@RequestMapping("/api/todos")
public class NotioController {

    private final NotioRepository notioRepository;

    public NotioController(NotioRepository notioRepository) {
        this.notioRepository = notioRepository;
    }

    @GetMapping
    public ResponseEntity<List<ToDo>> getToDos(Pageable pageable, Principal principal) {
        Page<ToDo> page = notioRepository.findByOwner(
                principal.getName(),
                PageRequest.of(
                        pageable.getPageNumber(),
                        pageable.getPageSize(),
                        pageable.getSortOr(Sort.by(Sort.Direction.ASC, "done"))
                )
        );

        return ResponseEntity.ok(page.getContent());
    }

    ...
}

为了减少测试时间,我想添加一些单元测试,并且仅使用以下测试类测试控制器:

@WebMvcTest(NotioController.class)
@ComponentScan(basePackages = {"com.example.controller"})
public class NotioControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private NotioRepository notioRepository;

    @Test
    @WithMockUser(roles="USER", username="tom")
    public void shouldReturnAPageWithUserSpecificToDos() throws Exception {
        ToDo[] toDos = {
                new ToDo(0L, "Get milk.", false, "tom"),
                new ToDo(1L, "Get bread.", true, "tom")
        };
        Page<ToDo> responsePage = new PageImpl<>(List.of(toDos));

        when(notioRepository.findByOwner("tom", PageRequest.of(0,2)))
                .thenReturn(responsePage);

        mvc.perform(
                get("/api/todos")
                        .param("page", "0")
                        .param("size", "2")
                        .contentType(MediaType.APPLICATION_JSON)

        )
                .andExpect(status().isOk())
                .andExpect(jsonPath("$").isArray());

    }

测试方法“shouldReturnAPageWithUserSpecificToDos”抛出以下异常:

java.lang.NullPointerException: Cannot invoke "org.springframework.data.domain.Page.getContent()" because "page" is null

在控制器方法中调用

return ResponseEntity.ok(page.getContent());
时发生。

但是,当我改变时

when(notioRepository.findByOwner("tom", PageRequest.of(0,2)))
                .thenReturn(responsePage);

when(notioRepository.findByOwner(any(String.class), any(Pageable.class)))
                .thenReturn(responsePage);

异常已解决。

我还没有弄清楚问题是什么,并且在有关存储库返回 null 的其他帖子中找不到任何帮助,因为它们的问题略有不同。

我也喜欢具体说明这个测试用例。

java spring mockito repository mockmvc
1个回答
0
投票

当您模拟存储库时,您仅传递带有页面和大小参数的 PageRequest 对象,但在控制器中您使用带有排序参数的 PageRequest。因此,您的模拟存储库将返回零,因为它没有针对该类型的 PageRequest 进行模拟。 更改测试中的 PageRequest 对象或将 ArgumentMatcher 保留为 PageRequest 的原样,它应该可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.