为什么.NET中没有IDateTimeProvider而DateTime有Now getter?

ryhaxcpt  于 2023-01-14  发布在  .NET
关注(0)|答案(5)|浏览(122)

目前我正在为一个组件编写一个单元测试,这个组件进行日期时间特定的验证。我已经创建了IDateTimeProvider接口,作为DateTime.UtcNow Package 器,业务对象使用接口而不是直接使用DateTime。DateTime似乎有点过载,应该拆分为一个值和一个从操作系统获取该值的东西。我想知道.NET中没有IDateTimeProviderIClock)接口是否有特殊的原因?

cig3rfwq

cig3rfwq1#

简单地说:因为BCL的大部分设计不是为了可测试性。
就“核心”功能而言,随机数生成也是如此--许多HTTP相关的类更难伪造:(至少在这种情况下,引入自己的时钟接口相当容易。
从好的方面来说,当Noda Time准备好投入生产使用时,它不仅提供了比BCL更好的日期/时间API,而且还提供了更易于测试的API:)

mctunoxg

mctunoxg2#

我们始终使用DateTimeProvider Package 类,如果需要,我们可以在测试上下文中覆盖它...

tp5buhyn

tp5buhyn3#

http://learn.typemock.com/typemock-isolator/能够模拟DateTime(* 和其他mscorlib类型 *),所以DateTime.现在不再是问题了。但缺点当然是这可能会导致开发人员设计得更差,因为模拟DateTime是没有问题的。现在!
也许使用IDateTimeProvider之类的东西是解决这类问题的更好的解决方案。
但是,如果您使用的是依赖于DateTime TypeMock-Isolatior的第三方库,则可能是一种解决方案/变通方法。
此外,微软研究院的鼹鼠/存根是很酷的东西:http://channel9.msdn.com/blogs/peli/moles-replace-any-net-method-with-a-delegate(显示如何用委托替换任何. NET方法/属性-例如DateTime.Now;-))

46qrfjad

46qrfjad4#

我把这个答案贴在了另一个问题上,但是如果您正在寻找一种简单的方法来测试DateTime.Now,它也适用于这里。
我喜欢做的是在需要当前日期/时间的类中创建一个返回DateTime(Func<DateTime>)的公共函数,并将其设置为返回DateTime(现在是默认值),然后在测试过程中,我用一个测试函数覆盖它,该测试函数返回我想要测试的任何DateTime。

public class MyClass
{
    public Func<DateTime> DateTimeNow = () => DateTime.Now;

    public void MyMethod()
    {
        var currentTime = DateTimeNow();
        //... do work
    }
}

public class MyClassTest
{
    public void TestMyMethod()
    {
        // Arrange
        var myClass = new MyClass();
        myClass.DateTimeNow = () => new DateTime(1999, 12, 31, 23, 59, 59);

        // Act
        myClass.MyMethod();

        // Assert
        // my asserts
    }
}
bxfogqkk

bxfogqkk5#

现在有几种开箱即用的替代方案:

我会使用第一个,尽管它的名称空间表明它是内部使用的,它是documented并且是公开的,它只有一个方法来获取当前的UTC时间,但是我不想让我的服务器依赖于时区。
当然,在datetime处理中有一些improvements,所以我们现在有相当多的类型可供使用。

  • 我们已经有了日期时间、时间跨度、时区信息、日期时间信息
  • 我们现在有DateOnly、TimeOnly

相关问题