c# - 单元测试 : DateTime. 现在

标签 c# unit-testing datetime mstest systemtime

我有一些单元测试期望“当前时间”与 DateTime.Now 不同,显然我不想更改计算机的时间。

实现这一目标的最佳策略是什么?

最佳答案

最佳策略是wrap the current time in an abstraction and inject that abstraction into the consumer .


或者,您还可以将时间抽象定义为环境上下文:

public abstract class TimeProvider
{
    private static TimeProvider current =
        DefaultTimeProvider.Instance;

    public static TimeProvider Current
    {
       get { return TimeProvider.current; }
       set 
       {
           if (value == null)
           {
               throw new ArgumentNullException("value");
           }
           TimeProvider.current = value; 
       }
   }

   public abstract DateTime UtcNow { get; }

   public static void ResetToDefault()
   {    
       TimeProvider.current = DefaultTimeProvider.Instance;
   }            
}

这将使您能够像这样使用它:

var now = TimeProvider.Current.UtcNow;

在单元测试中,您可以将 TimeProvider.Current 替换为 Test Double/Mock 对象。使用最小起订量的示例:

var timeMock = new Mock<TimeProvider>();
timeMock.SetupGet(tp => tp.UtcNow).Returns(new DateTime(2010, 3, 11));
TimeProvider.Current = timeMock.Object;

但是,当使用静态进行单元测试时,请始终记住通过调用 TimeProvider.ResetToDefault()拆除您的夹具

关于c# - 单元测试 : DateTime. 现在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2425721/

相关文章:

c# - 如何在 WPF TreeView 中添加和显示图像?

c# - 使用具有相同结构的两个不同表

c# - 如何从带有 NSubstitute 的模拟对象返回一个对象(即 List<string>)?

java - 使用 Java 8 lambda 表达式,按内部列表的属性过滤对象列表

javascript 从字符串创建日期 取决于浏览器

sql - MySQL为每一行自动存储日期时间

c# - 避免在每个 setter 中调用 RaisePropertyChanged

c# - 为什么以相反的顺序调用构造函数?

c# - 如何对使用 Servicestack Funq IOC 的 DBService 进行单元测试

c# - 模拟 Action<T> 以根据参数返回值