我尝试模拟以下存储库并根据所有者的名称返回一页待办事项条目。我正在使用“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 的其他帖子中找不到任何帮助,因为它们的问题略有不同。
我也喜欢具体说明这个测试用例。
当您模拟存储库时,您仅传递带有页面和大小参数的 PageRequest 对象,但在控制器中您使用带有排序参数的 PageRequest。因此,您的模拟存储库将返回零,因为它没有针对该类型的 PageRequest 进行模拟。 更改测试中的 PageRequest 对象或将 ArgumentMatcher 保留为 PageRequest 的原样,它应该可以工作。