2

注意:我对 Kotlin / JUnit 生态系统完全陌生,所以如果问题缺少基本内容,请多多包涵。

我正在研究基于 JSON 的文件格式。在单元/集成测试中,我想检查序列化是否生成与某些参考 JSON 树完全相同的 JSON 树。特别是我想确保序列化正确处理隐式或显式空值等微妙之处。

我已经以纯文件的形式添加了预期的 JSON.json作为测试资源,因此我现在可以加载预期 JSON 的字符串内容。我的问题是我的测试用例需要一些相当深/复杂的 JSON 树,如果比较失败,我找不到获得有意义的测试输出的好方法。例如,考虑 JSON 树深处某处只有一个值错误的情况。在 Rust 中,我使用例如rust-pretty-assertions 来解决这些问题:

在此处输入图像描述

我已经尝试过这些方法:

  1. 基于 的比较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返回 false,JUnit 只能打印它。

  2. 直接字符串比较:这当然不是完美的,因为 JSON 树可以相同,即使它们的字符串表示不同。但是我希望对它们进行漂亮的序列化可以让我在 JUnit 中使用某种字符串差异功能。到目前为止,我使用的是 JUnit 的 plain Assertions.assertEquals(actual, expected),不幸的是它只打印了两个字符串,说它们不相等,没有提示它们的不同之处。

kotlinx 或 JUnit 中是否有可以产生易于解释的测试失败输出的功能?

以防万一:我正在使用 JUnit 5,但我愿意接受替代方案。

4

1 回答 1

2

我建议尝试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!

它将为您的项目添加另一个依赖项,但它仅适用于测试范围,非常值得......

于 2021-12-27T08:25:28.050 回答