当主题是 DateTime 时,ShouldBeEquivalentTo 对等效对象失败

Posted

技术标签:

【中文标题】当主题是 DateTime 时,ShouldBeEquivalentTo 对等效对象失败【英文标题】:ShouldBeEquivalentTo failing for equivalent objects when the subject is a DateTime 【发布时间】:2013-12-14 00:04:59 【问题描述】:

我想要做什么

我刚刚设置了一个测试,以确保 NodaTime LocalDateTime 映射到 .NET DateTime,并保留相同的日期和时间值。我正在使用 FluentAssertions 的 ShouldBeEquivalentTo 方法来比较相应的属性值。

[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)
        );
    

问题

测试失败:

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)

我不知道最后两行是什么意思。

我尝试过的

    在调试器中运行测试以确认每个值都相同。 通过删除不同属性的 Includes 来查看问题是否是特定属性。 基于EquivalencyAssertionOptions&lt;DateTime&gt;.Empty() 的配置,以确保不隐式涉及额外的检查或属性。

    将所有内容简化为以下内容。

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

【问题讨论】:

我对 FluentAssertions 不熟悉......很遗憾它没有显示 which 属性不同(或者还有什么问题)。有没有办法让它提供更多信息? @JonSkeet,我认为它通常会给你一个特定的错误。看来这种特殊情况可能是个例外。 ShouldBeEquivalentTo() 旨在用于比较复杂的对象图而不是 .NET 框架的原始类型部分。异常报告末尾的特定操作意味着对于 DateTime 属性,它将使用内置的特定于 DateTime 的断言。显然,选定的属性之一是 DateTime 类型。 @DennisDoomen,在我的问题代码中,所有选定的属性都不是DateTime 类型。这是否意味着 FluentAssertions 中存在错误,还是我误解了您的意思? 否,但您是在 DateTime 而不是复杂类型上调用 ShouldBeEquivalentTo() 方法。我从来没有打算支持它。 【参考方案1】:

错误消息中的以下行表明正在对DateTime 进行某种特殊处理:

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

我尝试交换我正在比较的两个日期时间,这解决了问题:

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)
);

因此我得出结论,不应在 .NET 上调用 ShouldBeEquivalentTo DateTime

【讨论】:

也许您可以使用WithAutoConversion 选项解决此问题?或者,Fluent Assertions 5.0 版可能会解决这个问题? fluentassertions.com/objectgraphs/#auto-conversion【参考方案2】:

您可以将日期时间与流利的断言进行比较,他们现在添加了许多不错的方法来将其链接起来:

https://fluentassertions.com/datetimespans/

例如

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

【讨论】:

链接已失效。

以上是关于当主题是 DateTime 时,ShouldBeEquivalentTo 对等效对象失败的主要内容,如果未能解决你的问题,请参考以下文章

Breeze executeQuery Q 承诺失败 CORS

DateTime.Now 当网站上传到不同的服务器时造成问题

当服务器设置为 UTC 时创建夏时制感知 DateTime

Pandas - 合并具有时差的行(当 datetime 为索引时)

当存储为 UTC 时,如何全局序列化和反序列化 Date 与 DateTime?

Python Pandas:当日期小于 13 时,pandas.to_datetime() 正在切换日期和月份