java - 使用 AssertJ 在同一个对象上断言多个 JsonNode 路径?
问题描述
我使用的是assertj-core 3.9.1,但我也用我可用的最新版本3.16.1对此进行了测试。
我正在尝试使一些 assertj 断言更清晰一些。我们经常在非平凡的层次结构级别为各种对象断言多个子属性。我一直在使用“提取”从对象中提取简单的属性,但我现在要做的事情有点复杂,而且它不起作用。我所看到的似乎是 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”]。
我仍然有上面的原始断言,使用相同的表达式,所以我知道数据在那里。该表达式返回如下结构:
{
"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 断言。
推荐阅读
- css - 调整 p 元素大小时保持 p 元素附加到 h2 不移动
- c# - 如何将面板的大小设置为 tableLayout 的完整大小?
- python - 在python中拆分数据框
- reactjs - 如何通过 flowtype 定义 ref 类型?
- php - 回显一个数组值,给出另一个数组的键
- c# - Linq:ForEach 项目返回从该项目开始获取 n 个唯一项目所需的项目数
- regex - 如何按照某种模式获取字符串?
- python - 如何在 Python 中将 base64 编码的字符串转换为没有磁盘 I/O 的文件(用于 HTTP 请求)
- javascript - Javascript 中的月/日比较
- java - Cucumber Runner Class 未运行 Step Definitons