模拟日期时间

时间:2017-07-24 11:44:51

标签: c# mocking

public void DoSomethingAccordingToYear()
{
    if(DateTime.Now.Year < 2010)
        DoSomething();
    else
        DoSomethingElse();
}

我想测试一下这个方法。 如何在不更改代码和不使用接口的情况下模拟DateTime

2 个答案:

答案 0 :(得分:4)

执行此操作的一种常见方法是传入获取日期的组件。例如:

public interface IDateTimeNowProvider
{
    DateTime Now { get; }
}

public class DateTimeNowProvider : IDateTimeNowProvider
{
    public DateTime Now => DateTime.Now;
}

现在,您可以将IDateTimeNowProvider注入对象并进行模拟。

答案 1 :(得分:2)

如果更改方法的定义,则很简单:

public void DoSomethingAccordingToYear(DateTime testDate)
{
    if(testDate.Year < 2010)
        DoSomething();
    else
        DoSomethingElse();
}

然后这样称呼:

// production
DoSomethingAccordingToYear(DateTime.Now);

// test
DoSomethingAccordingToYear(new DateTime(2009,1,1));

修改

如果您不想改变调用方法的方式,您也可以像这样实现它:

public void DoSomethingAccordingToYear(DateTime? testDate = null)
{
    testDate = testDate ?? DateTime.Now;

    if (testDate.Year < 2010)
        DoSomething();
    else
        DoSomethingElse();
}

如果您在没有参数的情况下调用它,那么它将使用DateTime.Now,但您仍然可以传递参数进行测试。