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
}
}
5条答案
按热度按时间cig3rfwq1#
简单地说:因为BCL的大部分设计不是为了可测试性。
就“核心”功能而言,随机数生成也是如此--许多HTTP相关的类更难伪造:(至少在这种情况下,引入自己的时钟接口相当容易。
从好的方面来说,当Noda Time准备好投入生产使用时,它不仅提供了比BCL更好的日期/时间API,而且还提供了更易于测试的API:)
mctunoxg2#
我们始终使用DateTimeProvider Package 类,如果需要,我们可以在测试上下文中覆盖它...
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;-))
46qrfjad4#
我把这个答案贴在了另一个问题上,但是如果您正在寻找一种简单的方法来测试
DateTime.Now
,它也适用于这里。我喜欢做的是在需要当前日期/时间的类中创建一个返回DateTime(
Func<DateTime>
)的公共函数,并将其设置为返回DateTime(现在是默认值),然后在测试过程中,我用一个测试函数覆盖它,该测试函数返回我想要测试的任何DateTime。bxfogqkk5#
现在有几种开箱即用的替代方案:
我会使用第一个,尽管它的名称空间表明它是内部使用的,它是documented并且是公开的,它只有一个方法来获取当前的UTC时间,但是我不想让我的服务器依赖于时区。
当然,在datetime处理中有一些improvements,所以我们现在有相当多的类型可供使用。