FluentAssertions 基于反射的相等

Posted

技术标签:

【中文标题】FluentAssertions 基于反射的相等【英文标题】:FluentAssertions Reflection-based equal 【发布时间】:2012-03-11 12:44:04 【问题描述】:

我有一个简单的课程:

public class MyClass()

  public string Property1 get;set;
  public string Property2 get;set;

有没有办法在没有 Equal 方法实现的情况下断言这个类的两个实例是否相等(我猜反射在这里很适合)?我不想仅仅为了测试而实现 Equal。

【问题讨论】:

【参考方案1】:

请参阅官方文档的摘录: https://fluentassertions.com/introduction

您可以通过按名称比较它们的属性来断言整个对象的相等性。如果属性的类型不同但存在内置转换(通过 Convert 类),这甚至可以工作。例如,考虑某个任意域模型中的 Customer 实体及其 DTO 对应的 CustomerDto。您可以使用以下语法断言 DTO 与实体具有相同的值:

dto.ShouldHave().AllProperties().EqualTo(customer);

只要客户也可以使用 dto 的所有属性,并且它们的值相等或可转换,则断言成功。但是,您可以使用属性表达式排除特定属性,例如 ID 属性:

dto.ShouldHave().AllPropertiesBut(d => d.Id).EqualTo(customer);

相当于:

dto.ShouldHave().AllProperties().But(d => d.Id).EqualTo(customer);

反之亦然。因此,如果您只想包含两个特定属性,请使用此语法。

dto.ShouldHave().Properties(d => d.Name, d => d.Address).EqualTo(customer);

最后,如果你只想比较两个对象的属性,你可以像这样使用 SharedProperties() 方法:

  dto.ShouldHave().SharedProperties().EqualTo(customer);

显然,您可以使用 But() 方法将其链接起来以排除某些共享属性。

此外,您可以通过包含 IncludeNestedObjects 属性将结构比较进一步提高。这将指示比较比较主题的属性(在此示例中)引用的所有(集合)复杂类型。默认情况下,它将断言主题的嵌套属性与预期对象的嵌套属性匹配。但是,如果您确实指定了 SharedProperties,那么它只会比较嵌套对象之间同名的属性。例如:

dto.ShouldHave().SharedProperties().IncludingNestedObjects.EqualTo(customer);

【讨论】:

它验证属性相等,但不验证类型相等 这就是你所要求的,不是吗?如果要比较同一类的两个实例,为什么要检查类型相等性? 但我想确定我比较了相同类型的实例 那我不明白你对 Equals() 的评论。你永远无法用 Equals() 做到这一点。你可以做的是 collection.Should().OnlyContainItemsOfType()。 致未来的读者:请注意 FluentAssertions 的 API 已更改,现在通过 ShouldBeEquivalentTo(customer, opt => opt.Excluding(o => o.Id)) 实现这一点

以上是关于FluentAssertions 基于反射的相等的主要内容,如果未能解决你的问题,请参考以下文章

NUnit 或 Fluent Assertions 测试引用是不是相等?

如何将子集集合按值(结构平等)与 FluentAssertions 进行比较?

java使用反射比较两个bean对象属性值是否相等

Cook-Torrance光照模型

FluentAssertions - 比较包含名称相似但类型不同的属性的对象

为啥 Python 没有“__req__”(反射相等)方法?