如何比较 kotlinx 中的实际序列化结果和预期序列化结果?
How to compare actual and expected serialization result in kotlinx?
注意:我是 Kotlin/JUnit 生态系统的新手,所以如果问题缺少一些基本内容,请耐心等待。
我正在研究基于 JSON 的文件格式。在 unit/integration 测试中,我想检查序列化生成的 JSON 树是否与某些参考 JSON 树完全相同。特别是我想确保序列化正确处理隐式或显式空值等细微之处。
我以普通 .json
文件的形式添加了预期的 JSON 作为测试资源,这样我现在可以加载预期的 JSON 的字符串内容。我的问题是我的测试用例需要一些 deep/complex JSON 树,如果比较失败,我找不到 获得有意义的测试输出的好方法。例如,考虑 JSON 树深处某处只有一个值错误的情况。在 Rust 中,我正在使用 rust-pretty-assertions 来解决这些问题:
我已经尝试过这些方法:
比较基于JsonElement
。我基本上使用:
val actualContent: String = ... # from serialization
val expectedContent: String = ... # from test fixture
val actual = Json.parseToJsonElement(actualContent)
val expected = Json.parseToJsonElement(expectedContent)
Assertions.assertEquals(actual, expected)
不幸的是,如果比较失败,测试输出只包含一行 org.opentest4j.AssertionFailedError: expected: <{ ... long unformatted JSON ...}>
,这使得很难发现断言失败的实际原因。当然,这种行为是有道理的,因为如果 JsonElement.equals
returns false,JUnit 只能打印它。
直接字符串比较:这当然不是完美的,因为JSON-树即使字符串表示不同也可以是相同的。然而,我希望对它们进行漂亮的序列化将允许我在 JUnit 中使用某种字符串差异功能。到目前为止,我使用的是 JUnit 的普通 Assertions.assertEquals(actual, expected)
,不幸的是它只打印两个字符串,说它们不相等,没有提示它们不同的地方。
kotlinx 或 JUnit 中是否有可以生成易于解释的测试失败输出的功能?
以防万一:我使用的是 JUnit 5,但我愿意接受其他选择。
我建议尝试 JsonUnit。它将允许您为 json 编写断言,并在失败时显示良好的消息。使用 AssertJ 集成的示例:
assertThatJson(actual).isEqualTo(expectedJson)
...可能会在与您的示例类似的示例中产生以下输出:
Comparing expected:
{"lorem":"Hello, Wrold!","ipsum":42,"dolor":{"value":"hey ho!"}}
------------
with actual:
{"lorem":"Hello, World!","ipsum":42,"dolor":{"value":"hey"}}
Different value found in node "dolor.value", expected: <"hey ho!"> but was: <"hey">.
Comparison Failure:
Expected :hey ho!
Actual :hey
Different value found in node "lorem", expected: <"Hello, Wrold!"> but was: <"Hello, World!">.
Comparison Failure:
Expected :Hello, Wrold!
Actual :Hello, World!
它将为您的项目添加另一个依赖项,但它仅用于测试范围,非常值得...
注意:我是 Kotlin/JUnit 生态系统的新手,所以如果问题缺少一些基本内容,请耐心等待。
我正在研究基于 JSON 的文件格式。在 unit/integration 测试中,我想检查序列化生成的 JSON 树是否与某些参考 JSON 树完全相同。特别是我想确保序列化正确处理隐式或显式空值等细微之处。
我以普通 .json
文件的形式添加了预期的 JSON 作为测试资源,这样我现在可以加载预期的 JSON 的字符串内容。我的问题是我的测试用例需要一些 deep/complex JSON 树,如果比较失败,我找不到 获得有意义的测试输出的好方法。例如,考虑 JSON 树深处某处只有一个值错误的情况。在 Rust 中,我正在使用 rust-pretty-assertions 来解决这些问题:
我已经尝试过这些方法:
比较基于
JsonElement
。我基本上使用:val actualContent: String = ... # from serialization val expectedContent: String = ... # from test fixture val actual = Json.parseToJsonElement(actualContent) val expected = Json.parseToJsonElement(expectedContent) Assertions.assertEquals(actual, expected)
不幸的是,如果比较失败,测试输出只包含一行
org.opentest4j.AssertionFailedError: expected: <{ ... long unformatted JSON ...}>
,这使得很难发现断言失败的实际原因。当然,这种行为是有道理的,因为如果JsonElement.equals
returns false,JUnit 只能打印它。直接字符串比较:这当然不是完美的,因为JSON-树即使字符串表示不同也可以是相同的。然而,我希望对它们进行漂亮的序列化将允许我在 JUnit 中使用某种字符串差异功能。到目前为止,我使用的是 JUnit 的普通
Assertions.assertEquals(actual, expected)
,不幸的是它只打印两个字符串,说它们不相等,没有提示它们不同的地方。
kotlinx 或 JUnit 中是否有可以生成易于解释的测试失败输出的功能?
以防万一:我使用的是 JUnit 5,但我愿意接受其他选择。
我建议尝试 JsonUnit。它将允许您为 json 编写断言,并在失败时显示良好的消息。使用 AssertJ 集成的示例:
assertThatJson(actual).isEqualTo(expectedJson)
...可能会在与您的示例类似的示例中产生以下输出:
Comparing expected:
{"lorem":"Hello, Wrold!","ipsum":42,"dolor":{"value":"hey ho!"}}
------------
with actual:
{"lorem":"Hello, World!","ipsum":42,"dolor":{"value":"hey"}}
Different value found in node "dolor.value", expected: <"hey ho!"> but was: <"hey">.
Comparison Failure:
Expected :hey ho!
Actual :hey
Different value found in node "lorem", expected: <"Hello, Wrold!"> but was: <"Hello, World!">.
Comparison Failure:
Expected :Hello, Wrold!
Actual :Hello, World!
它将为您的项目添加另一个依赖项,但它仅用于测试范围,非常值得...