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

目前我正在为一个进行日期时间特定validation的组件编写unit testing。 我创建了IDateTimeProvider接口,它充当DateTime.UtcNow包装器,业务对象直接使用接口而不是DateTime 。 看起来DateTime有点过载,应该分成一个值和一个从操作系统中获取该值的东西。 我想知道在.NET中是否有特殊原因没有IDateTimeProviderIClock )接口?

简单地说:因为BCL的大部分不是为可测试性而设计的。

就“核心”function而言,随机数生成也是如此 – 并且许多与HTTP相关的类更糟糕的假装:(至少在这种情况下,引入自己的时钟接口相当容易。

从好的方面来说,当Noda Time准备好用于生产时,它不仅会提供比BCL更好的日期/时间API – 它将提供更加测试友好的:)

我们一直使用DateTimeProvider包装器类,如果需要,我们可以在测试环境中覆盖它…

http://learn.typemock.com/typemock-isolator/能够模拟DateTime( 以及其他mscorlib类型 ),因此DateTime.Now不再是问题。 但缺点当然是这可能导致开发人员设计他们的东西更加糟糕,因为模拟DateTime没有问题。现在!

也许使用像IDateTimeProvider这样的东西是更好的解决方案。

但是如果你正在使用第三方lib继电器,例如DateTime TypeMock-Isolatior可能是一个解决方案/解决方法。

微软研究院的Moles / Stub也很酷: http : //channel9.msdn.com/blogs/peli/moles-replace-any-net-method-with-a-delegate (演示了如何替换任何.NET方法/属性)与代表 – 例如DateTime.Now ;-))

我将此答案发布到另一个问题,但如果您正在寻找一种测试DateTime.Now的简单方法,它也适用于此。

我喜欢做的是创建一个公共函数,该函数在需要当前日期/时间的类中返回DateTime( Func ),并将其设置为默认返回DateTime.Now。 然后,在测试期间,我使用测试函数覆盖它,该函数返回我想要测试的任何DateTime。

 public class MyClass { public Func 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 } }