为何测试repository.delete()无需模拟?测试用例仍通过
为什么未模拟
libraryRepository.delete(...)测试仍能通过? 先贴出你的代码:
@DeleteMapping(value = ["/library/books/{id}"]) fun deleteBook( @PathVariable("id") id: kotlin.Int): ResponseEntity<Unit> { return ResponseEntity(service.deleteBook(id), HttpStatus.valueOf(200)) } override fun deleteBook(id: Int) { libraryRepository.findById(id).let { if(it == null){ throw NotFoundException("Book with the given id not found") } libraryRepository.delete(it) } } @Test fun `delete book and return 200`(){ val library = Library(name = "testName", author = "testAuthor") `when`(libraryRepository.findById(1)).thenReturn(library) mvc.perform(MockMvcRequestBuilders.delete("/library/books/1")) .andExpect(MockMvcResultMatchers.status().isOk) verify(libraryRepository).delete(library) }
核心原因
Mockito 对无返回值(void)的方法有默认行为:当你没有主动模拟这类方法时,它不会抛出任何异常,只会执行空操作(什么都不做)。
你的libraryRepository.delete()是void方法,所以即使没写doNothing().when(libraryRepository).delete(any())这类模拟语句,代码调用到它时也不会中断流程——跳过实际删除逻辑后,代码正常走到返回200的步骤,自然能通过状态码校验。
另外,你测试用例里的verify(libraryRepository).delete(library)已经在验证delete方法是否被正确调用了,这其实已经覆盖了"代码执行到删除步骤"的关键逻辑,所以测试通过是完全合理的,你的预期(测试失败)本身是错误的。
补充说明
如果希望未被模拟的方法调用时抛出异常,可以开启Mockito的严格模式,比如在测试类上添加@MockitoSettings(strictness = Strictness.STRICT_STUBS),这样未存根的方法调用就会触发错误,符合你最初的预期。
内容的提问来源于stack exchange,提问作者Johny
相关产品推荐
相关产品推荐

