FluentAssertions: equivalence of sorted lists
Asked Answered
M

8

69

I'm trying to establish equivalence of two lists using FluentAssertions in C#, where two things are of importance:

  1. the elements are compared by the values they hold, not by reference (i.e. they are equivalent, not equal)
  2. the order of the elements in the lists is important

Is there no function in FluentAssertions (or even NUnit) that does this?

Cheers!

Methodology answered 10/10, 2014 at 9:8 Comment(0)
C
120

By default, ShouldBeEquivalentTo() will ignore the order in the collections because in most cases two collections are equivalent if they contain the same items in any order. If you do care about the order, just use one of the overloads of WithStrictOrdering() on the options => parameter.

Example:

var myList = Enumerable.Range(1, 5);
var expected = new[]
{
    1, 2, 3, 4, 5
};

//succeeds
myList.ShouldBeEquivalentTo(expected, options => options.WithStrictOrdering());

//fails
myList.Reverse().ShouldBeEquivalentTo(expected, options => options.WithStrictOrdering());

Read more about these options in the documentation.

Comradery answered 10/10, 2014 at 10:40 Comment(4)
Perfect, exactly what I was hoping for. Thanks for introducing me to the options parameter! :)Methodology
Took me too long to realize Should().BeEquivalentTo() apparently isn't the same as ShouldBeEquivalentTo()....Minute
I'm fixing this in 5.0. See github.com/fluentassertions/fluentassertions/pull/593Comradery
Any particular reason NotBeEquivalentTo doesn't have an overload with options? I need to verify that two enumerables are equivalent, but not in the same order.Mannerly
H
22

Late to the game here but I use the Fluent Assertions version of this here:

actualRows.Should().BeEquivalentTo(expectedRows,options => options.WithStrictOrdering());

It will check all the values of all the properties for equivalence, and with this option, the order matters. If the order does not matter, omit the options param and it will make sure the item from one collection will exist somewhere in the other. Hope this helps someone

Hillaryhillbilly answered 14/3, 2017 at 15:22 Comment(1)
With the latest fluentassertions nuget, you have to use it as follows: actualRows.Should().BeEquivalentTo(expectedRows,options => options.WithStrictOrdering());Waterworks
S
5

I think you can just do:

myObject.List.SequenceEqual(myOtherObject.ListToCompare).Should().BeTrue();

This will only work if the elements in the list are equal when using Object.Equal(element1, element2)

if this is not the case then you need to implement your own EqualityComparer for the objedts in the lists then use:

myObject.List.SequenceEqual(myOtherObject.ListToCompare, myEqualityComparer)
             .Should().BeTrue();
Sines answered 10/10, 2014 at 9:43 Comment(1)
I reckon this is as neat as it can get. Thanks!Methodology
H
4

From this post.

The newer ShouldBeEquivalentTo() introduced in FA 2.0 is doing an in-depth structural comparison and also reporting on any differences

You can achieve it in this way.

actual.Should().BeEquivalentTo(expectation, c => c.WithStrictOrdering());
Habitual answered 25/2, 2020 at 2:47 Comment(1)
Just noting that one can configure FluentAssertions to use this option by default: fluentassertions.com/tips/#using-global-assertionoptionsLamellicorn
C
1

You want the ShouldAllBeEquivalentTo method, that should compare the values of the properties of the two object graphs in a list.

*Edit: I'd probably use the Linq Sequence equal with a custom equality comparer that uses ShouldBeEquivalentTo to care about the order of the elements.

Confabulation answered 10/10, 2014 at 9:21 Comment(2)
Already tried that, doesn't care about the order of elements. Edit -> That was my thought as well, I was just hoping I had overlooked a function somewhere.Methodology
Maybe try SequenceEqual and a custom equality comparer then.Confabulation
C
1

During my struggle with similar task found out about next method:

IEnumerable collection = new[] { 1, 2, 5, 8 };

collection
    .Should()
    .ContainInOrder(new[] { 1, 5, 8 });

Collection Assertions Docs

Crowe answered 26/1, 2018 at 12:52 Comment(0)
C
1

For part 2 of this question, checking the order of the elements in a collection, as of 2020 (not sure which version this was introduced, am using v5.10.3 currently) you can use:

mySimpleCollection.Should().BeInDescendingOrder() or myComplexCollection.Should().BeInDescendingOrder(x => x.SomeProperty)

OR

mySimpleCollection.Should().BeInAscendingOrder() or myComplexCollection.Should().BeInAscendingOrder(x => x.SomeProperty)

OR

mySimpleCollection.Should().NotBeInAscendingOrder() or myComplexCollection.Should().NotBeInAscendingOrder(x => x.SomeProperty)

OR

mySimpleCollection.Should().NotBeInDescendingOrder() or myComplexCollection.Should().NotBeInDescendingOrder(x => x.SomeProperty)

Chesson answered 13/4, 2020 at 17:18 Comment(0)
R
0

The Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert class may have a method responding to your needs.

CollectionAssert.AreEqual Method (ICollection, ICollection, IComparer) should do the trick.

Two collections are equal if they have the same elements in the same order and quantity. Elements are equal if their values are equal, not if they refer to the same object.

Rom answered 10/10, 2014 at 9:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.