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
相关产品推荐
相关产品推荐

