【问题标题】:Why does this unit test fail when testing DateTime equality?为什么这个单元测试在测试 DateTime 相等性时会失败?
【发布时间】:2010-09-26 17:11:28
【问题描述】:

在 .NET 3.5 上使用 NUnit 2.2,以下测试在使用 DateTime.Equals 时失败。为什么?

[TestFixture]
public class AttributeValueModelTest
{
    public class HasDate
    {
        public DateTime? DateValue
        {
            get
            {
                DateTime value;
                return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
            }
        }

        public object ObjectValue { get; set; }
    }

    [Test]
    public void TwoDates()
    {
        DateTime actual = DateTime.Now;
        var date = new HasDate {ObjectValue = actual};
        Assert.IsTrue(date.DateValue.Value.Equals(actual));
    }
}

【问题讨论】:

  • 只是好奇,有什么理由坚持使用 NUnit 2.2 吗? 2.8似乎是最新的
  • 我不会努力坚持使用 2.2。它只在我的机器上,因为它带有 TestDriven.NET 以及 2.4。我错过了什么?

标签: unit-testing datetime .net-3.5 nunit


【解决方案1】:

日期不相等。 TryParse 会掉一些滴答声。比较 Tick 值。

对于一次测试运行:

Console.WriteLine(date.DateValue.Value.Ticks);
Console.WriteLine(actual.Ticks);

产量:

633646934930000000
633646934936763185

【讨论】:

  • 我花了一点时间,但在两个日期之间创建了一个 TimeSpan 后我想通了。为你 +1。
【解决方案2】:

问题其实不是 TryParse,而是 ToString()。

DateTime 对象以精确到百万分之一秒的精度(如果不准确)开始。 ToString() 将其转换为字符串,精度仅为一秒。

TryParse 正在尽其所能。

如果您添加格式说明符(沿"yyyy-MM-dd HH:mm:ss.ffffff" 行),它应该可以工作。

【讨论】:

  • 嗯,Object.ToString() 不采用格式说明符。有什么建议吗?
【解决方案3】:

要指定包含所有精度的格式,可以使用 String.Format() 方法。 James 给出的示例如下所示:

String.Format("{0:yyyy-MM-dd HH:mm:ss.ffffff}", ObjectValue);

我不知道当你传递一些不是约会的东西时会发生什么。

也许更简单的方法是在您已经获得日期对象时添加一个特殊情况:

    public DateTime? DateValue
    {
        get
        {
            DateTime value = ObjectValue as DateTime;
            if (value != null) return value;
            return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
        }
    }

【讨论】:

    【解决方案4】:
    public DateTime? DateValue { get { DateTime value; bool isDate = DateTime.TryParse(ObjectValue.ToString(), out value); return isDate ? new DateTime?(value) : new DateTime?(); } }

    【讨论】:

    • 我还没有运行代码。这纯粹是基于一目了然。对不起,如果我没有任何帮助。
    • 抱歉,问题出在 TryParse。
    • 谢谢。当我查看代码时,它看起来像是在返回 DateTime(当 TryParse 成功时)而不是 DateTime?。我在这里学到的一件事是您可以将 DateTime 的实例分配给 DateTime? :)
    【解决方案5】:

    我不知道这在 .NET 中是否相同,但在 Java 中,equals 通常只会比较实例是否相同,而不是值是否相同。您应该使用 compareTo。

    【讨论】:

    • 不,在 Java 中,== 运算符用于引用相等,而 equals() 方法用于值相等。
    • @Adam:默认情况下不是。您必须重写 Object 的 equals 方法才能获得您所描述的行为。
    • 在苏维埃俄罗斯,== 等于 Object.Equals
    • @亚当。保守地编码你总是假设它比较实例,因为这是最常见的情况。走另一条路有时会给你带来麻烦,需要一段时间来调试。只有当你绝对知道你应该使用equals()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多