Yuriy.FluentAssertions 1.0.0

dotnet add package Yuriy.FluentAssertions --version 1.0.0                
NuGet\Install-Package Yuriy.FluentAssertions -Version 1.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Yuriy.FluentAssertions" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Yuriy.FluentAssertions --version 1.0.0                
#r "nuget: Yuriy.FluentAssertions, 1.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Yuriy.FluentAssertions as a Cake Addin
#addin nuget:?package=Yuriy.FluentAssertions&version=1.0.0

// Install Yuriy.FluentAssertions as a Cake Tool
#tool nuget:?package=Yuriy.FluentAssertions&version=1.0.0                

Yuriy.FluentAssertions

Provides additional methods to use whith FluentAssertions.

Avalable as Yuriy.FluentAssertions nuget package.

Collection comparison with custom EqualityComparer

Let's assume there is an Item class defined like this:

public class Item
{
    public int IntProp { get; set; }

    public string StringProp { get; set; }

    public static Item ItemOne => new Item{IntProp = 1, StringProp = "One"};
    public static Item ItemTwo => new Item{IntProp = 2, StringProp = "Two"};    
}

By default FluentAssertions rely on Equals method of collection elements when comparing two collections for equality. For example, if class Item does not overload the Equals method, the following test will fail:

var collection = new [] {Item.ItemOne, Item.ItemTwo};
var similarCollection = new [] {Item.ItemOne, Item.ItemTwo};

collection.Should().Equal(similarCollection);

One way to solve it is to override the Item.Equals method in a way that works for your test. The disadvantage of this approach is that your test-only logic now added to a class from your business domain. Also, you might want different ways to compare items in different tests, but there is only one Equals method. You might also do not have an access to the source code of the Item class.

Another way to solve this problem is to use one of FluentAssertion's Equal method overloads like this:

collection.Should().Equal(similarCollection, (x, y) => x.IntProp == y.IntProp && string.Equals(x.StringProp => y.StringProp));

This is typically what I use in this situation. The only downside is that it might be a bit repetetive even if I extract the equality comparison logic in a static method. It might be a bit more convinient to write your comparison logic once and use it in your tests everywhere. Enter EqualWithComparer method.

Let's define our comparison logic that we want to use in unit tests (you might even have it already defined in your domain logic and if it suits the tests than you can just use it):

private sealed class ByAllPropsComparer : IEqualityComparer<Item>
{
    public bool Equals(Item x, Item y) => x.IntProp == y.IntProp && string.Equals(x.StringProp, y.StringProp);

    public int GetHashCode(Item obj) => throw new Exception("not used in tests");
}

Now we can register it once and use in all our tests:

FluentAssertions.EqualityExtentions.RegisterComparer<ByAllPropsComparer>();

And the following test should pass as we use EqualWithComparer method:

var collection = new [] {Item.ItemOne, Item.ItemTwo};
var similarCollection = new [] {Item.ItemOne, Item.ItemTwo};

collection.Should().EqualWithComparer(similarCollection);

What if for a particula test we need to some other comparison logic? Use EqualWithComparer method overload that accepts a comparer. It will be used instead of any previously registered comparers:

var collection = new [] {Item.ItemOne, Item.ItemTwo};
var similarCollection = new [] {Item.ItemOne, Item.ItemTwo};

collection.Should().EqualWithComparer(similarCollection, new SomeOtherComparer());
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 3,901 7/27/2018

Initial release with extension methods to allow using costom EqualityComparer when assertin collections equality.