使用 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 断言。
我使用的是 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 断言。