单元测试:在模拟中克服 DateTime.Now
单元测试经常依赖于特定的时间戳,但是修改系统时间可能并不理想。本文探讨了模拟 DateTime.Now 的有效策略。
抽象和注入
首选方法是将当前时间封装在一个抽象(例如,TimeProvider)中,并将其注入到使用者中。这允许您在测试期间替换模拟 TimeProvider,同时保留原始实现以用于生产环境。
环境上下文
或者,您可以将时间抽象定义为环境上下文,这允许您修改当前时间,而无需直接修改系统时间。这是一个环境上下文实现的示例:
<code>public abstract class TimeProvider { private static TimeProvider current = DefaultTimeProvider.Instance; public static TimeProvider Current { get { return current; } set { current = value; } } public abstract DateTime UtcNow { get; } }</code>
在此上下文中,TimeProvider.Current 表示当前时间。要在测试中使用它,您可以将 TimeProvider.Current 替换为模拟对象:
<code>using Moq; var timeMock = new Mock<TimeProvider>(); timeMock.SetupGet(tp => tp.UtcNow).Returns(new DateTime(2010, 3, 11)); TimeProvider.Current = timeMock.Object;</code>
这允许单元测试设置特定时间戳,而不会影响生产代码。但是,重要的是要记住在每次测试后将时间提供程序重置为其默认状态。
以上是如何在单元测试中有效模拟 DateTime.Now?的详细内容。更多信息请关注PHP中文网其他相关文章!