I get this (expected) error when asserting properties with different types:
Expected property a.Date to be System.String, but found System.DateTime.
I would like to assert the equality between a string representation of a date to a nullable DateTime without doing a manual assert as I would rather try to specify some kind of a rule or relationship due to a high number of properties to be asserted, than first excluding them from the BeEquivalentTo and then assert them one-by-one with:
a.DateX.Should().Be(b.DateX.ToNullableDateTime());
I have a minimal example below just to demonstrate the issue:
[TestFixture]
public class MyTests
{
[Test]
public void ShouldMapDates()
{
//Arrange
var b = new B { Date = "01.01.0001" };
//Act
var a = B.MapToA(b);
//Assert
a.Should().BeEquivalentTo(b, c =>
{
//Magic configuration here?
});
}
}
public class A
{
public DateTime? Date { get; set; }
}
public class B
{
public string Date { get; set; }
public static A MapToA(B b)
{
return new A { Date = b.Date.ToNullableDateTime() };
}
}
Any ideas?
ToNullableDateTime is an extension method and I expect that I would have to use it in the assertion config somehow. I also have an extension method on DateTime? to convert back to the same string format at my disposal
Using FluentAssertions v6.11
Edit Solved:
public class DateEqualityStep : IEquivalencyStep
{
public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator)
{
if (context.CurrentNode.IsRoot)
{
return EquivalencyResult.ContinueWithNext;
}
if (comparands.Subject?.GetType() != typeof(DateTime) || comparands.RuntimeType != typeof(string))
{
return EquivalencyResult.ContinueWithNext;
}
var subject = (DateTime?)comparands.Subject;
var expectation = (string)comparands.Expectation;
subject.Should().Be(expectation.ToNullableDateTime(), context.Reason.FormattedMessage, context.Reason.Arguments);
return EquivalencyResult.AssertionCompleted;
}
}
Usage:
a.Should().BeEquivalentTo(b, c => c.Using(new DateEqualityStep()));
This is good enough for my scenario
I'd do this:
This avoids your problem entirely.
Addendum: I'd also write a set of unit tests for
ToNullableDateTime().