ShouldBeEquivalentTo failing for equivalent objects when the subject is a DateTime

只愿长相守 提交于 2019-12-24 15:32:05

问题


What I'm trying to do

I've just set up a test to ensure that a NodaTime LocalDateTime is mapped to a .NET DateTime, retaining the same date and time values. I'm using FluentAssertions' ShouldBeEquivalentTo method to compare the corresponding property values.

[TestClass]
public class LocalDateTimeMapping
{
    [TestMethod]
    public void RetainsComponentValues()
    {
        var nodatimeTime = new LocalDateTime();
        var dotnetTime = nodatimeTime.ToDateTimeUnspecified();

        dotnetTime.ShouldBeEquivalentTo(nodatimeTime,
            o => o
                .Including(d => d.Year)
                .Including(d => d.Month)
                .Including(d => d.Day)
                .Including(d => d.Hour)
                .Including(d => d.Minute)
                .Including(d => d.Second)
                .Including(d => d.Millisecond)
        );
    }
}

The problem

The test is failing:

Expected subject to be 01/01/1970 00:00:00, but found <1970-01-01>.

With configuration:
- Select property System.DateTime.Year
- Select property System.DateTime.Month
- Select property System.DateTime.Day
- Select property System.DateTime.Hour
- Select property System.DateTime.Minute
- Select property System.DateTime.Second
- Select property System.DateTime.Millisecond
- Match property by name (or throw)
- Invoke Action<DateTime> when info.RuntimeType.IsSameOrInherits(System.DateTime)
- Invoke Action<String> when info.RuntimeType.IsSameOrInherits(System.String)

I don't know what the last two lines mean.

What I've tried

  1. Running the test in the debugger to confirm that the values of each of these were the same.
  2. Seeing if the problem was a specific property by removing the Includes for the different properties.
  3. Basing the configuration on EquivalencyAssertionOptions<DateTime>.Empty() to ensure that no extra checks or properties were implicitly involved.
  4. Simplifying it all down to just the following.

    dotnetTime.ShouldBeEquivalentTo(nodatimeTime,
        o => EquivalencyAssertionOptions<DateTime>.Empty()
    );
    

回答1:


The following line from the error message indicated that some sort of special treatment was being given to the DateTime:

Invoke Action<DateTime> when info.RuntimeType.IsSameOrInherits(System.DateTime)

I tried swapping the two date-times I was comparing, and this resolved the problem:

nodatimeTime.ShouldBeEquivalentTo(dotnetTime,
    o => o
        .Including(d => d.Year)
        .Including(d => d.Month)
        .Including(d => d.Day)
        .Including(d => d.Hour)
        .Including(d => d.Minute)
        .Including(d => d.Second)
        .Including(d => d.Millisecond)
);

So I conclude that ShouldBeEquivalentTo should not be called on a .NET DateTime.




回答2:


You can compare datetimes with fluent assertions, they have added lots of nice methods to chain it up now:

https://fluentassertions.com/datetimespans/

e.g.

theDatetime.Should().BeLessThan(10.Minutes()).Before(otherDatetime);


来源:https://stackoverflow.com/questions/20257861/shouldbeequivalentto-failing-for-equivalent-objects-when-the-subject-is-a-dateti

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!