FluentAssertions Should().BeEquivalentTo() fails with Lists containing run-time specified types deriving from identical interface
Asked Answered
C

1

11

I have the following test illustrating a simple example of what im attempting to achieve (comparison of two equivalent lists):

[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);
}

Ideally, each list should be able to contain any number of items of different types deriving from the IDomainEvent interface. The test currently fails. I'm suspecting it has something to do with Should().BeEquivalentTo not being fit to compare run-time specified types. How do i configure this example, so that the test passes?

Currently the test results are:

[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
Cylindroid answered 14/8, 2018 at 17:27 Comment(2)
Does BusinessCreatedDomainEvent override equals, etc.?Aquatint
I came to this page only to realize I was using a wrong method to compare 2 lists. I needed to use list1.Should().Equal(list2) instead. Leaving it here just in case someone else has the same problemCultural
C
32

I suspect that the interface IDomainEvent is without any public properties. That explains the exception you're seeing, as the logic in BeEquivalentTo() uses the properties on IDomainEvent as the lists are of type List<IDomainEvent>.

To compare the two lists using the properties on BusinessCreatedDomainEvent instead, you can instead use

list1.Should().BeEquivalentTo(list2, options => options.RespectingRuntimeTypes());

From the documentation

By default, Fluent Assertions respects an object’s or member’s declared (compile-time) type when selecting members to process during a recursive comparison. That is to say if the subject is a OrderDto but the variable it is assigned to has type Dto only the members defined by the latter class would be considered when comparing the object to the order variable. This behavior can be configured and you can choose to use run-time types if you prefer:

Chequerboard answered 14/8, 2018 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.