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

MockK无法区分命令子类类型,如何按类型返回模拟结果?

我之前也碰到过这个坑,本质是JVM泛型类型擦除搞的鬼,MockK没法靠泛型父类的类型参数精准区分这两个命令。给你几个靠谱的解决办法:

方法1:用match匹配器检查实例类型

直接判断传入的命令到底是哪个子类,这种方式最直观,不会出错:

@Test
fun `getActiveIndices should make correct calls`() {
    val aliases = listOf(/* 你的AliasModel列表 */)
    val indices = listOf(/* 你的IndexModel列表 */)
    
    // 精准匹配GetAllAliasesCommand类型的实例
    every { 
        elasticsearchCommandExecutor.execute(match { it is GetAllAliasesCommand }) 
    } returns aliases
    
    // 精准匹配GetAllIndicesCommand类型的实例
    every { 
        elasticsearchCommandExecutor.execute(match { it is GetAllIndicesCommand }) 
    } returns indices
    
    val result = indexService.getActiveIndices(ElasticsearchCluster.SOME_CLUSTER)
    
    verify(exactly = 1) { elasticsearchCommandExecutor.execute(any<GetAllAliasesCommand>()) }
    verify(exactly = 1) { elasticsearchCommandExecutor.execute(any<GetAllIndicesCommand>()) }
    assert(result == /* 预期的IndexModel列表 */)
}

方法2:用ofType匹配器(更简洁)

MockK专门提供了ofType<T>()匹配器,用来匹配指定类型的实例,写法更清爽:

@Test
fun `getActiveIndices should make correct calls`() {
    val aliases = listOf(/* 你的AliasModel列表 */)
    val indices = listOf(/* 你的IndexModel列表 */)
    
    every { elasticsearchCommandExecutor.execute(ofType<GetAllAliasesCommand>()) } returns aliases
    every { elasticsearchCommandExecutor.execute(ofType<GetAllIndicesCommand>()) } returns indices
    
    val result = indexService.getActiveIndices(ElasticsearchCluster.SOME_CLUSTER)
    
    verify(exactly = 1) { elasticsearchCommandExecutor.execute(ofType<GetAllAliasesCommand>()) }
    verify(exactly = 1) { elasticsearchCommandExecutor.execute(ofType<GetAllIndicesCommand>()) }
    assert(result == /* 预期的IndexModel列表 */)
}

方法3:直接用具体命令实例匹配(最稳妥)

如果你的命令类可以直接实例化,干脆用具体的实例来匹配,绝对不会混淆:

@Test
fun `getActiveIndices should make correct calls`() {
    val aliases = listOf(/* 你的AliasModel列表 */)
    val indices = listOf(/* 你的IndexModel列表 */)
    val aliasesCommand = GetAllAliasesCommand(ElasticsearchCluster.SOME_CLUSTER)
    val indicesCommand = GetAllIndicesCommand(ElasticsearchCluster.SOME_CLUSTER)
    
    every { elasticsearchCommandExecutor.execute(aliasesCommand) } returns aliases
    every { elasticsearchCommandExecutor.execute(indicesCommand) } returns indices
    
    val result = indexService.getActiveIndices(ElasticsearchCluster.SOME_CLUSTER)
    
    verify(exactly = 1) { elasticsearchCommandExecutor.execute(aliasesCommand) }
    verify(exactly = 1) { elasticsearchCommandExecutor.execute(indicesCommand) }
    assert(result == /* 预期的IndexModel列表 */)
}

为啥原来的写法会失效?

核心原因是JVM泛型类型擦除:虽然GetAllAliasesCommand和GetAllIndicesCommand是ElasticsearchCommand<T>的不同子类,但运行时泛型参数会被擦除,MockK没法通过any<CommandType>()精准区分这两个命令的泛型父类类型,导致最后一条every规则覆盖了前面的。

用上面的方法明确匹配实例的具体类型,就能绕开这个问题啦。

内容的提问来源于stack exchange,提问作者Enes Keles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:37:48