【发布时间】:2020-06-12 16:06:02
【问题描述】:
Fluent Assertions 库通过Should().BeEquivalentTo 方法和相关方法非常强调其comparing object graphs 的功能。正如文档指出的那样:
Should().BeEquivalentTo是一个非常强大的功能,也是 Fluent Assertions 的独特卖点之一。
通过阅读示例,我得到的印象是对象图必须通过对象引用来连接。
现在,我有很多我想检查其内容的对象图和树,但它们通常是从文件或数据库中加载的。 因此,连接仅通过跨对象匹配的 ID 属性值存在。
例如,想象一下这个简单的结构(这里以 JSON 格式编写)- 示例 A:
[{
"Id": 1,
"Name": "Foo",
"NextId": 2
}, {
"Id": 2,
"Name": "Bar"
}]
我想使用 Fluent Assertions 来检查此类对象图的结构。
也就是说,无论Id 和NextId 字段实际具有什么值,第一个对象中的NextId 必须与第二个对象中的Id 具有相同的值。
因此,任何具有两个不同 Id 值的两个对象的集合,其中一个对象的 NextId 值等于另一个对象的 Id 值,都可以。
示例 B:
[{
"Key": 5,
"LinkedTo": [3]
}, {
"Key": 10,
"LinkedTo": []
}, {
"Key": 3,
"LinkedTo": [5]
}]
在这里,具有三个不同Key 值的三个对象的任何集合,其中两个对象在其LinkedTo 属性中引用彼此的键,而其余对象在其LinkedTo 属性中具有一个空数组应该匹配。
示例 C:
[{
"Id": 1,
"Owner": 4
}, {
"Id": 2,
"Owner": 4
}, {
"Id": 3,
"Owner": 4
}, {
"Id": 4
}]
在这里,如果其中三个对象的 Owner 属性的值与其余对象的 Id 属性匹配,则具有三个不同 Id 值的任何四个对象的集合都将匹配。
这可以通过BeEquivalentTo 以某种方式完成吗?
请注意,我确实不想在应用任何断言之前遍历我的对象并添加实际的对象引用,因为该操作本身可能会引入其自身的错误。
编辑:根据要求,以下是上述示例的几个匹配和不匹配图表:
示例 A:
匹配:
[{
"Id": 5,
"Name": "Foo",
"NextId": -8
}, {
"Id": -8,
"Name": "Bar"
}]
匹配:
[{
"Id": 200,
"Name": "Bar"
}, {
"Id": 30,
"Name": "Foo",
"NextId": 200
}]
不匹配:
[{
"Id": 3,
"Name": "Bar",
"NextId": 6
}, {
"Id": 6,
"Name": "Foo"
}]
示例 B:
匹配:
[{
"Key": 20,
"LinkedTo": [7]
}, {
"Key": 8,
"LinkedTo": []
}, {
"Key": 7,
"LinkedTo": [20]
}]
匹配:
[{
"Key": 9,
"LinkedTo": [100]
}, {
"Key": 100,
"LinkedTo": [9]
}, {
"Key": 3,
"LinkedTo": []
}]
不匹配:
[{
"Key": 5,
"LinkedTo": [10]
}, {
"Key": 10,
"LinkedTo": []
}, {
"Key": 3,
"LinkedTo": [5]
}]
示例 C:
匹配:
[{
"Id": 1
}, {
"Id": 2,
"Owner": 1
}, {
"Id": 3,
"Owner": 1
}, {
"Id": 4,
"Owner": 1
}]
匹配:
[{
"Id": 10,
"Owner": 20
}, {
"Id": 30,
"Owner": 20
}, {
"Id": 20
}, {
"Id": 40,
"Owner": 20
}]
不匹配:
[{
"Id": 8,
"Owner": 2
}, {
"Id": 12,
"Owner": 8
}, {
"Id": 54,
"Owner": 2
}, {
"Id": 2
}]
【问题讨论】:
-
您想要断言您的数据究竟是什么?
BeEquivalentTo将断言集合具有相同数量的元素,并且A中的每个元素在B中具有匹配项,其中所有属性都具有等效值(递归地使用相同的等效逻辑)。测试是否在您期望它通过的地方失败?你能分享一个完整的代码测试吗? -
@JamesFaix:我不知道如何为此编写测试代码。我想断言第一个元素中的
NextId与第二个元素中的Id具有相同的值——无论该值是 2、5 还是 369。我想等价逻辑会以某种方式包括之间的映射来自我预期数据的 ID 和在实际数据中找到的 ID。 -
BeEquivalentTo最常用于断言 subject,例如针对预期值的函数返回值。您是否尝试断言有关您的代码的一些不变量?您能否提供一个应该匹配的主题+期望对,而另一对应该匹配失败? -
@JonasNyrup:完成。 (更详细地说:对于 expected 图的三个示例中的每一个,我添加了两个匹配的 subjects 和一个匹配失败的 subject .)
标签: c# .net unit-testing fluent-assertions