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

Kotlin测试报错:预期SingletonMap实际为LinkedHashMap如何解决

问题解答

根因分析

  • Map的equals规范仅比较键值对的内容,和具体实现类无关,SingletonMap和LinkedHashMap只要键值对完全匹配就会判定相等,因此实现类差异不是报错的直接原因。
  • 真正的错误来源于集合类型不匹配:你在预期值中使用arrayOf构造了KotlinArray类型的列表,而GraphQL的toSpecification()方法返回的结构中,数组对应的实际类型是List。二者的toString输出格式相似,所以打印出来看起来内容一致,但equals会判定不相等。
  • 额外补充:即使实际返回的也是Array类型,Kotlin中Array的equals默认是引用比较,只有两个变量指向同一个数组实例才会判定相等,和内容无关,也会导致断言失败。

修复方案

方案1:替换预期值的集合类型

直接把arrayOf修改为listOf,匹配GraphQL返回的集合类型即可:

assertThat(result["data"]).isEqualTo(
  mapOf(
    "cashCustomerTransactions" to listOf( // 此处将arrayOf改为listOf
      mapOf(
        "createdAt" to "2019-03-20T18:26:18Z",
        "id" to "TOKEN",
        "reasonCode" to "CARD_PRESENT_PURCHASE"
      )
    )
  )
)

方案2:分层断言更稳妥

如果担心嵌套结构还有其他类型差异,可以逐层提取字段做断言:

assertThat(result["errors"]).isNull()
val data = result["data"] as Map<String, *>
val transactions = data["cashCustomerTransactions"] as List<Map<String, *>>
assertThat(transactions).containsExactly(
  mapOf(
    "createdAt" to "2019-03-20T18:26:18Z",
    "id" to "TOKEN",
    "reasonCode" to "CARD_PRESENT_PURCHASE"
  )
)

方案3:JSON序列化后比较

如果要完全规避集合实现类的干扰,可以将两个对象序列化为JSON字符串后再做比较:

// 用项目中已引入的JSON序列化工具即可,比如Jackson、Gson
val expectedData = mapOf(
  "cashCustomerTransactions" to listOf(
    mapOf(
      "createdAt" to "2019-03-20T18:26:18Z",
      "id" to "TOKEN",
      "reasonCode" to "CARD_PRESENT_PURCHASE"
    )
  )
)
val expectedJson = objectMapper.writeValueAsString(expectedData)
val actualJson = objectMapper.writeValueAsString(result["data"])
assertThat(actualJson).isEqualTo(expectedJson)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:39:00