You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重写含DateTime属性的对象Equals方法以通过单元测试?

问题分析

核心问题是Model类的Edited属性默认赋值为DateTime.Now,你创建expected对象的时间与getModel()返回result对象的时间存在微小时间差,导致Equals方法里的精确时间比较始终失败。

解决方案

方案1:统一测试中的时间值

你的初步方案思路可行,还可以优化得更清晰:要么用实际结果的时间构建预期对象,要么同步两个对象的时间值:

public void MyTest()
{
    Model result = cut.getModel();
    // 用实际结果的时间构建预期对象,彻底避免时间差
    Model expected = new() { Id = 1, Editor = "Me", Edited = result.Edited };
    Assert.AreEqual(expected, result);
}

或者:

public void MyTest()
{
    Model expected = new() { Id = 1, Editor = "Me"};
    Model result = cut.getModel();
    // 同步两个对象的时间值
    expected.Edited = result.Edited;
    Assert.AreEqual(expected, result);
}

方案2:修改Equals方法忽略Edited字段

如果Edited仅用于记录修改时间,不参与业务层面的对象相等判断,可以直接在Equals中移除该字段的比较逻辑:

public override bool Equals(object obj)
{
    var myObj = obj as Model;
    if (myObj == null)
        return false;
    return myObj.Id == Id &&
           myObj.Editor == Editor;
    // 移除Edited的比较逻辑
}

注意:这种修改必须符合业务需求,确保忽略时间字段不会影响其他场景的相等判断。

方案3:宽松的时间比较

如果需要保留时间比较但允许微小误差(比如毫秒级差异),可以调整Equals里的时间判断逻辑,验证时间差是否在可接受范围内:

public override bool Equals(object obj)
{
    var myObj = obj as Model;
    if (myObj == null)
        return false;
    // 判断时间差是否在1秒内(阈值可根据需求调整)
    var timeDiff = Math.Abs((myObj.Edited - Edited).TotalMilliseconds);
    return myObj.Id == Id &&
           myObj.Editor == Editor &&
           timeDiff < 1000;
}

方案4:逐个字段断言(更灵活)

放弃依赖重载的Equals,直接在测试中对关键字段分别断言,这种方式更直观,无需修改业务类逻辑:

public void MyTest()
{
    Model expected = new() { Id = 1, Editor = "Me"};
    Model result = cut.getModel();
    
    Assert.AreEqual(expected.Id, result.Id);
    Assert.AreEqual(expected.Editor, result.Editor);
    // 如需验证时间,可做宽松判断
    Assert.That(result.Edited, Is.EqualTo(DateTime.Now).Within(1).Seconds);
}

内容的提问来源于stack exchange,提问作者Alberto Martín

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:15:43