You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:45:36