Search code examples
c#unit-testingfluent-assertions

Fluent Assertions: Equivalency of two lists of arrays, with arrays needing strict ordering


I'm trying to use Fluent Assertions to test a permutation generating algorithm. The algorithm generates a List<int[]>, where the List order does not matter, but the elements of each int[] do.

[Fact]
public void Are_all_permutations_generated()
{
    // Arrange
    var expected = new List<int[]>
    {
        new[] { 1, 2, 3 },
        new[] { 1, 3, 2 },
        new[] { 2, 1, 3 },
        new[] { 2, 3, 1 },
        new[] { 3, 1, 2 },
        new[] { 3, 2, 1 }
    };

    // Act
    var result = new List<int[]>
    {
        new[] { 3, 2, 1 },
        new[] { 1, 3, 2 },
        new[] { 2, 3, 1 },
        new[] { 2, 1, 3 },
        new[] { 3, 1, 2 },
        new[] { 1, 2, 3 }
    };

    // Assert
    result.Should().BeEquivalentTo(expected);
}

If I use result.Should().BeEquivalentTo(expected) as in the above code block it would pass even if result was

var result = new List<int[]>
{
    new[] { 1, 2, 3 },
    new[] { 1, 2, 3 },
    new[] { 1, 2, 3 },
    new[] { 1, 2, 3 },
    new[] { 1, 2, 3 },
    new[] { 1, 2, 3 }
};

How can I write the Fluent Assertions to allow any order for the list, but have strict ordering for the arrays so that it can assert all the permutations have been found? Is there someway of writing the options in the BeEquivalentTo to do this?


Solution

  • Use WithStrictOrderingFor to determine when you want to use strict ordering or not. It takes a lambda that gives you access to the IObjectInfo, an object that exposes all kinds of relevant information that you can use. Something like

    WithStrictOrderingFor(info => info.RuntimeType == typeof(int[]))