模拟计算机系统日期时间

Mar*_*ane 3 c# windows-services mocking

我在C#中构建了一个Windows服务,它根据当前的日期和时间从数据库中调用实时时间序列数据.
我在测试数据库中有测试数据,我想用它来计算数据是否以正确的方式使用.
我想知道是否有人使用过应用程序或有任何其他方法在本地计算机上"模拟"系统日期.例如,我可以运行此应用程序并将其设置为将系统日期设置为指定日期.

任何建议都会很棒.

slo*_*oth 11

只需封装您对DateTime.Now界面后面的属性的访问权限.

public interface IDateTimeProvider
{
    DateTime Now { get; }
}
Run Code Online (Sandbox Code Playgroud)

在您的代码中,使用如下实现:

public class DateTimeProvider : IDateTimeProvider
{
    public DateTime Now { get { return DateTime.Now; } }
}
Run Code Online (Sandbox Code Playgroud)

对于您的测试,您可以IDateTimeProvider通过创建测试类或使用模拟框架进行模拟.

如果将此接口与依赖注入等技术一起使用,即使在运行时也很容易改变服务的行为.

你可以创建一个IDateTimeProvider总是休息一小时的东西:

public class AlwaysToLateDateTimeProvider : IDateTimeProvider
{
    public DateTime Now { get { return DateTime.Now.AddHours(-2); } }
}
Run Code Online (Sandbox Code Playgroud)

或创建一个从文件,数据库,管道等读取"模拟"日期时间的实现.

在测试时,您将配置您的服务以使用其中一个实现,并且在实时模式下运行时,只需配置您的依赖注入以使用返回"正确"日期时间的普通实现.


当然还有TypeMock隔离器 ......

Isolate.WhenCalled(() => DateTime.Now).WillReturn(new DateTime(2008, 1, 1));
Run Code Online (Sandbox Code Playgroud)


Mha*_*lin 4

我现在已经使用它来覆盖,例如在运行测试时。在使用 DateTime.Now 的实际实现中,您使用新的 SystemTime.Now 代替。在您的测试中,您只需将 Now 设置为返回您选择的值的不同函数。

public static class SystemTime
{
    private static Func<DateTime> now = () => DateTime.Now;

    public static Func<DateTime> Now
    {
        get { return now; }
        set { now = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试中的用法示例:

SystemTime.Now = () => DateTime.Now.AddMinutes(20);
Run Code Online (Sandbox Code Playgroud)

在单元测试拆解中,将其设置回来很重要SystemTime.Now = () => DateTime.Now

正常使用:

DateTime now = SystemTime.Now();
Run Code Online (Sandbox Code Playgroud)

  • +1表示好主意。如果使用此代码,请确保在您的 unittest-teardown-code 中恢复 now-lamda 表达式的原始值。否则,根据之前的运行测试,其他单元测试可能会显示意外的结果。 (3认同)