FluentAssertions adds many helpful ways of comparing data in order to check for "equality" beyond a simple direct comparison (for example check for equivalence across types, across collections, automatically converting types, ignoring elements of types, using fuzzy matching for dates and more).
Making a "fluent assertion" on something will automatically integrate with your test framework, registering a failed test if something doesn't quite match.
e.g. to compare an object excluding the DateCreated element:
actual.Should()
.BeEquivalentTo(expected, cfg => cfg.Excluding(p => p.DateCreated));
However, sometimes the "actual" value you want to make the assertion on is only available as part of a Moq Verify statement, which only supports matching based on a boolean return type.
e.g.
myMock.Verify(m =>
m.Method(It.Is<MyData>(actual =>
actual == expected));
As you can see above, replacing "==" with a "Fluent" assertion is not possible out of the box. However there is a trick you can use by setting up the below helper method:
public static class FluentVerifier
{
public static bool VerifyFluentAssertion(Action assertion)
{
using (var assertionScope = new AssertionScope())
{
assertion();
return !assertionScope.Discard().Any();
}
}
public static async Task<bool> VerifyFluentAssertion(Func<Task> assertion)
{
using (var assertionScope = new AssertionScope())
{
await assertion();
return !assertionScope.Discard().Any();
}
}
}
Now you can nest the Fluent Assertion inside of the Verify statement as follows:
myMock.Verify(m =>
m.Method(It.Is<MyData>(actual =>
FluentVerifier.VerifyFluentAssertion(() =>
actual.Should()
.BeEquivalentTo(expected, cfg => cfg.Excluding(p => p.DateCreated), ""))));
Note however that since Lambda expressions can't contain calls to methods with optional parameters, you must specify the "becauseArgs" parameter of the "BeEquivalentTo" method.