James Wood
James Wood

Reputation: 17562

Use of `ShouldBeEquivalentTo`, `ShouldAllBeEquivalentTo`, and `BeEquivalentTo`

I am working with fluent assertions in my unit tests, however the use of ShouldBeEquivalentTo, ShouldAllBeEquivalentTo, and BeEquivalentTo is unclear.

For example; all the following statements pass so the functions appear equivalent.

List<string> a = new List<string>() { "james", "wood" };
List<string> b = new List<string>() { "james", "wood" };

a.ShouldBeEquivalentTo(b);
a.ShouldAllBeEquivalentTo(b);
a.Should().BeEquivalentTo(b);

Why should I use one rather than the another?

Upvotes: 10

Views: 6408

Answers (2)

Dennis Doomen
Dennis Doomen

Reputation: 8899

ShouldBeEquivalentTo and ShouldAllBeEquivalentTo are the same and will do a recursive structural comparison. But since the behavior is highly configurable, some of the options support using property expressions to include or exclude certain members. However, the T in the expression refers to the type of the root object (List<string>) when ShouldBeEquivalentTo is used, and string if ShouldAllBeEquivalentTo is used. The former acts on the entire object whereas the latter acts on IEnumerable<T>.

Should().BeEquivalentTo() is a much simpler implementation which will just do an order-insensitive comparison using Equals. This method will be removed in the next breaking change (v5.x).

Upvotes: 12

Voicu
Voicu

Reputation: 56

As concept, a list is viewed as a single unit. Thus, from the readability point of view, choosing one of your options, the single valid call is "a.ShouldBeEquivalentTo(b);".

Regarding others, they are obscure.

The plural form "ShouldAllBeEquivalentTo" is applied when comparing 2 collections of elements. I think, one would argue that we are comparing these group of strings (A) with these group of strings (B). What happened here, the group of strings was gathered as a whole single concept under a List data structure type. Thus, I would say it is wrong to use this call.

The last form implies 2 things. First, object "a" should be transformed into something. The name "Should" doesn't communicate anything. Afterwards, the result should be compared if it is equivalent with a list object "b". Logically, one should compare 2 objects of same type. There is no need for an additional transformation.

When reading code, I would prefer the following format:

A list "A" is equivalent with another list "B".

List<string> a = new List<string>() { "james", "wood" };
List<string> b = new List<string>() { "james", "wood" };

//creating "IsEquivalentTo" method
bool listsAreEqual = a.IsEquivalentTo(b);

//creating "IsEqualTo" method
listsAreEqual = a.IsEqualTo(b);

//overloading operator ==
listsAreEqual = (a == b);

Upvotes: -3

Related Questions