使用 AssertJ 在同一对象上断言多个 JsonNode 路径?

Using AssertJ to assert multiple JsonNode paths on the same object?

我使用的是 assertj-core 3.9.1,但我也用我可用的最新版本 3.16.1 对此进行了测试。

我正在尝试使一些 assertj 断言更清晰一些。对于各种对象,我们经常在非平凡的层次结构级别断言多个子属性。我一直在使用“提取”从一个对象中提取简单的属性,但我现在想做的有点复杂,而且它不起作用。我所看到的 SEEMS 就像 assertj 中的错误,但我不确定它为什么在做它正在做的事情。

我从这样的事情开始:

assertThat(expression).at("/content/liability").asText()).isEqualTo("CRU");
assertThat(expression).at("/content/enterpriseType").asText()).isEqualTo("GBS");

我想改为做这样的事情:

assertThat(expression)
    .extracting(jn -> jn.at("/content/liability").asText(),
                jn -> jn.at("/content/enterpriseType").asText())
    .containsExactly("CRU", "GBS");

这失败了,基本上是说我希望“[]”(一个空列表)等于 [“CRU”,“GBS”]。

我还有上面的原始断言,使用相同的表达式,所以我知道数据在那里。表达式 returns 结构如下:

{
  "content": {
    ...
    "enterpriseType": "GBS",
    ...
    "liability": "CRU",
    ...
  }
}

所以,然后我尝试将断言更改为:

assertThat(expression))
    .extracting(jn -> textAtPath(jn, "/content/liability"),
                jn -> textAtPath(jn, "/content/enterpriseType"))
    .containsExactly(tuple("CRU", "GBS"));

有:

private String textAtPath(JsonNode node, String path) {
    return node.at(path).asText();
}

然后我 运行 在“textAtPath”中使用断点进行测试。我在那里看到的东西看起来很正常,直到我仔细观察。当我查看“节点”的值时,我看到了一些看起来非常像我上面显示的结构的东西,但又不完全是:

{
  ...
  "enterpriseType": "GBS",
  ...
  "liability": "CRU",
  ...
}

由于某种原因,传递给传递给“extracting()”的lambda的值是原始结构的CHILD节点。

我尝试更改测试,使两个路径字符串为“/liability”和“/enterpriseType”。测试通过了。我不会就这样离开,因为这没有意义。

我相信 https://github.com/joel-costigliola/assertj-core/issues/1954 中对此进行了讨论。

这里的微妙之处在于,如果 expression 是可迭代的,assertThat(expression) 将提供可迭代的断言,并且 extracting 将应用于可迭代的元素。

另一方面,如果 assertThat(expression) 已返回对象断言,extracting 将应用于表达式。

我还强烈建议使用 JsonUnit 进行 JSON 断言。