如何为Kotlin按ID删除方法编写单元测试?解决MockK调用报错
问题描述
我有一段Kotlin的delete方法代码:
fun delete(id: Long) { NotFoundExceptionValidator(!dishOfTheDayEntityRepository.existsById(id), "dishOfTheDay not found") dishOfTheDayEntityRepository.deleteById(id) }
其中NotFoundExceptionValidator用于检查条件并抛出异常。我编写了对应的单元测试:
@ConcurrentExecution internal class DishOfTheDayServiceTest { private val repo: DishOfTheDayEntityRepository = mockk() private val mapper: DishOfTheDayMapper = mockk() private val dishOfTheDayEntityService = DishOfTheDayService(repo, mapper) @Test fun `delete should work properly`() { //given val id: Long = 1; //when dishOfTheDayEntityService.delete(1) //then verify(exactly = 1) { repo.deleteById(1) } } }
运行测试时抛出错误:
no answer found for: DishOfTheDayEntityRepository(#1).existsById(1) io.mockk.MockKException: no answer found for: DishOfTheDayEntityRepository(#1).existsById(1)
请问如何正确编写该方法的单元测试并解决此报错?
解决方案
报错原因是MockK创建的repo对象未为existsById方法预设返回值,调用该方法时找不到对应的响应。需要针对两种业务场景编写测试:
1. 正常删除(ID存在)的测试
先为existsById设置返回true,确保NotFoundExceptionValidator不触发异常,后续deleteById正常执行:
@Test fun `delete should execute successfully when id exists`() { // given val id = 1L every { repo.existsById(id) } returns true // when dishOfTheDayEntityService.delete(id) // then verify(exactly = 1) { repo.existsById(id) } verify(exactly = 1) { repo.deleteById(id) } }
2. 删除不存在ID时抛出异常的测试
为existsById设置返回false,验证是否正确抛出指定异常:
@Test fun `delete should throw NotFoundException when id does not exist`() { // given val id = 1L every { repo.existsById(id) } returns false // when + then val exception = shouldThrow<NotFoundException> { dishOfTheDayEntityService.delete(id) } assertEquals("dishOfTheDay not found", exception.message) verify(exactly = 1) { repo.existsById(id) } verify(exactly = 0) { repo.deleteById(id) } // 确认删除方法未被调用 }
核心要点
- 必须用
every { ... } returns ...为Mock对象的所有被调用方法预设返回值,这是MockK的基础用法。 - 异常场景用
shouldThrow验证异常类型和信息,确保逻辑符合预期。 - 验证时覆盖所有关键方法的调用次数,保证流程执行完整。
内容的提问来源于stack exchange,提问作者engineering_the_future
相关产品推荐
相关产品推荐

