Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用DateTimeOffset对象的单元测试类的正确方法?_C#_Unit Testing_Datetime_Testing_Nunit - Fatal编程技术网

C# 使用DateTimeOffset对象的单元测试类的正确方法?

C# 使用DateTimeOffset对象的单元测试类的正确方法?,c#,unit-testing,datetime,testing,nunit,C#,Unit Testing,Datetime,Testing,Nunit,我希望您提供有关如何正确测试使用DateTimeOffset实例的代码的信息或示例。我知道测试必须是确定性的 那么,如何将应用程序与DateTimeOffset类隔离呢?当然,我希望能够使用一个假的DateTimeOffset。现在,等等 在我的测试中,我是否应该使用以下内容: var myDate = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-3)); 或者我会使用像MyCustomDateTime

我希望您提供有关如何正确测试使用DateTimeOffset实例的代码的信息或示例。我知道测试必须是确定性的

那么,如何将应用程序与DateTimeOffset类隔离呢?当然,我希望能够使用一个假的DateTimeOffset。现在,等等

在我的测试中,我是否应该使用以下内容:

var myDate = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-3));
或者我会使用像MyCustomDateTimeOffset这样的包装类吗? 我是否应该在代码中根本不使用DateTimeOffset,而是使用包装器呢?

正如上面所说:

我们可以通过引入额外级别的间接寻址来解决任何问题

您不需要真正的包装器,只需要避免
DateTimeOffset.Now
/
DateTimeOffset.UtcNow

以下是几种处理方法:

  • 如果使用依赖项注入,请编写一个
    IClock
    接口,该接口公开
    Now
    /
    UtcNow
    属性

    public interface IClock
    {
        DateTimeOffset Now { get; }
        DateTimeOffset UtcNow { get; }
    }
    
    internal class Clock : IClock
    {
        public DateTimeOffset Now => DateTimeOffset.Now;
        public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
    }
    
    在测试中,您只需按照自己的意愿模拟接口

  • 如果您希望继续使用静态属性,请编写一个静态类型,比如说
    Clock
    ,然后使用它

    public static class Clock
    {
        internal static Func<DateTimeOffset> DateTimeOffsetProvider { get; set; }
            = () => DateTimeOffset.Now;
    
        public static DateTimeOffset Now => DateTimeOffsetProvider();
        public static DateTimeOffset UtcNow => DateTimeOffsetProvider().ToUniversalTime();
    }
    

    • 因为您不知道DateTimeOffSet的值。现在,您就不能断言该DateTimeOffSet。现在等于一个值

      您可能应该重构以使用以下两种方法之一:

      • 依赖注入
      • 接口和包装器
      依赖注入(DI) DI意味着不让方法确定日期,而是传入它

      这种方法

      public void DoSomething()
      {
         var now = DateTimeOffSet.Now;
         // Do other stuff with the date
      }
      
      。你会改成这种方法吗

      public void DoSomething(DateTimeOffSet dtos)
      {
         // Do other stuff with the date
      }
      
      接口和包装器
      您的另一个选项(尽管最终您也会使用DI)是创建接口和包装器。然后在对象中使用接口,而不是具体的DateTimeOffSet,这样就可以使用MOQ或其他测试库来MOQ接口。以SystemWrapper()项目为例。

      谢谢,但是第二个版本(我更喜欢)能与.NET 2.0项目一起工作吗?你知道在.NET2.0中有没有其他方法可以做到这一点吗?感谢在.NET2中使用,您只需要用自定义委托替换
      Func
      ,我在答案中添加了一些代码。
      public void DoSomething(DateTimeOffSet dtos)
      {
         // Do other stuff with the date
      }