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

Controller测试遇MockkException:AuthService.create无应答

问题原因与解决方法

核心原因:对象相等性不匹配

Mockk 默认通过对象的 equals() 方法匹配方法调用的参数。你的 signup 测试失败,本质是Controller 调用 authService.create() 时传入的 Account 实例,和测试代码里定义的 account 实例不是同一个对象,且 Account 类未正确重写 equals() 和 hashCode()——默认的 equals() 比较对象引用,只要不是同一个实例就会匹配失败。

而 signin 测试能成功,大概率是因为:

  • signin 接口参数是简单类型(如用户名、密码字符串),不存在对象引用问题;
  • 或你在 signin 测试中直接将同一个 Account 实例传给了 Controller,参数引用完全一致,所以匹配成功。

解决方法

1. 重写 Account 类的 equals() 和 hashCode()

让属性值相同的 Account 实例被视为相等,即使是不同实例,只要属性一致就能匹配。最简单的方式是用 Kotlin 数据类(自动生成 equals() 和 hashCode()):

data class Account(val username: String, val password: String)

如果不是数据类,手动重写:

class Account(val username: String, val password: String) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        other as Account
        if (username != other.username) return false
        if (password != other.password) return false
        return true
    }

    override fun hashCode(): Int {
        var result = username.hashCode()
        result = 31 * result + password.hashCode()
        return result
    }
}

2. 使用 Mockk 匹配器验证属性

如果不想修改 Account 类,可以用 match 匹配器检查传入对象的属性是否符合预期:

every { authService.create(match { 
    it.username == account.username && it.password == account.password 
}) } returns expectedSignupResult

3. 捕获参数后断言属性

通过 slot 捕获调用时传入的 Account 实例,测试执行后验证其属性是否和预期一致:

// 定义捕获槽
val capturedAccount = slot<Account>()
// 配置 mock 时捕获参数
every { authService.create(capture(capturedAccount)) } returns expectedSignupResult

// 执行 signup 测试请求
mockMvc.perform(post("/signup")...).andExpect(status().isOk)

// 断言捕获的实例属性
assertEquals(account.username, capturedAccount.captured.username)
assertEquals(account.password, capturedAccount.captured.password)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:05:08