使用FluentAssertions Should().BeEquivalentTo()比较包含运行时指定类型的列表,这些类型都派生自相同的接口时会失败。

11

我有以下测试,演示了一个我尝试实现的简单例子(比较两个等价列表):

[Fact]
public void Test()
{
    // Arrange
    var list1 = new List<IDomainEvent> { new BusinessCreatedDomainEvent { Name = "Microsoft" } };
    var list2 = new List<IDomainEvent> { new BusinessCreatedDomainEvent { Name = "Microsoft" } };

    // Act

    // Assert
    list1.Should().BeEquivalentTo(list2);
}

理想情况下,每个列表都应该能够包含任意数量的不同类型项目,这些项目派生自IDomainEvent接口。目前测试失败了。我怀疑与Should().BeEquivalentTo无法比较运行时指定类型有关。如何配置此示例,使测试通过?
当前测试结果为:
[8/14/2018 5:21:26 PM Error] [xUnit.net 00:00:00.7909767]     BusinessWrite.UnitTests.Infrastructure.EventStoreUnitTests.Test [FAIL]
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7922005]       System.InvalidOperationException : No members were found for comparison. Please specify some members to include in the comparison or choose a more meaningful assertion.
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7932461]       Stack Trace:
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7941986]         C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\GenericEnumerableEquivalencyStep.cs(74,0): at FluentAssertions.Equivalency.GenericEnumerableEquivalencyStep.Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7945426]         C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EquivalencyValidator.cs(85,0): at FluentAssertions.Equivalency.EquivalencyValidator.AssertEqualityUsing(IEquivalencyValidationContext context)
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7946187]         C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Equivalency\EquivalencyValidator.cs(38,0): at FluentAssertions.Equivalency.EquivalencyValidator.AssertEquality(EquivalencyValidationContext context)
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7946610]         C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Collections\CollectionAssertions.cs(394,0): at FluentAssertions.Collections.CollectionAssertions`2.BeEquivalentTo[TExpectation](IEnumerable`1 expectation, Func`2 config, String because, Object[] becauseArgs)
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7947629]         C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Collections\CollectionAssertions.cs(331,0): at FluentAssertions.Collections.CollectionAssertions`2.BeEquivalentTo[TExpectation](IEnumerable`1 expectation, String because, Object[] becauseArgs)
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.7948569]         C:\Users\Christian\source\repos\unify\src\Services\Business\BusinessWrite\BusinessWrite.UnitTests\Infrastructure\EventStoreUnitTests.cs(43,0): at BusinessWrite.UnitTests.Infrastructure.EventStoreUnitTests.Test()
[8/14/2018 5:21:26 PM Informational] [xUnit.net 00:00:00.8058517]   Finished:    BusinessWrite.UnitTests

2
BusinessCreatedDomainEvent 是否覆盖了 equals 等方法? - JSteward
我来到这个页面才意识到我在比较两个列表时使用了错误的方法。我需要使用list1.Should().Equal(list2)。我把它留在这里,以防其他人遇到同样的问题。 - Artemious
1个回答

31
我怀疑接口IDomainEvent没有任何public属性。 这就解释了你所看到的异常情况,因为BeEquivalentTo()中的逻辑使用IDomainEvent上的属性,而列表是List<IDomainEvent>类型。 要改用在BusinessCreatedDomainEvent上使用属性来比较这两个列表,可以使用以下方法:
list1.Should().BeEquivalentTo(list2, options => options.RespectingRuntimeTypes());

根据文档,Fluent Assertions默认尊重对象或成员在编译时声明的类型,在递归比较过程中选择要处理的成员。也就是说,如果主体是OrderDto,但它被分配给的变量具有Dto类型,则仅考虑由后者类定义的成员来将对象与订单变量进行比较。您可以配置此行为,并选择使用运行时类型:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接