C# 用于单元测试的DateTime接口

C# 用于单元测试的DateTime接口,c#,unit-testing,datetime,C#,Unit Testing,Datetime,您好,我为datetime创建了如下界面: public interface ITimeProvider<T> { T Now { get; } string ToShortDateString(); } public class DateTimeProvider : ITimeProvider<DateTime> { private DateTime _date; public DateTime Now {

您好,我为datetime创建了如下界面:

public interface ITimeProvider<T>
{
    T Now { get; }
    string ToShortDateString();
}
public class DateTimeProvider : ITimeProvider<DateTime>
{

    private DateTime _date;

    public DateTime Now
    {
        get { return DateTime.Now; }
    }

    public  DateTimeProvider()
    {

        _date = new DateTime();
    }
    public string ToShortDateString()
    {
        return _date.ToShortDateString();
    }
}
这不起作用,因为我没有指定类型。我可以这么做

public ITimeProvider<DateTime> _timeProvider { get;set; }
public ITimeProvider\u timeProvider{get;set;}
但那样的话,我就不能使用另一个时间提供者了。我还考虑过(这是我能想到的唯一解决方案)使ATM成为通用的,就像这样

 public class Atm<T> : IAtm
 {
      public ITimeProvider<T> _timeProvider { get;set; }
 }
公共级Atm:IAtm
{
公共ITimeProvider _timeProvider{get;set;}
}
但是我觉得我不能使用属性注入,有没有其他方法可以这样做,这样我就可以测试它?

使用它可以对系统或其他不受您控制的程序集进行单元测试

[TestClass]
public class TestClass1
{ 
        [TestMethod]
        public void TestCurrentYear()
        {
            int fixedYear = 2000;

            // Shims can be used only in a ShimsContext:
            using (ShimsContext.Create())
            {
                // Arrange:
                // Shim DateTime.Now to return a fixed date:
                System.Fakes.ShimDateTime.NowGet = 
                () =>
                { return new DateTime(fixedYear, 1, 1); };

                // Instantiate the component under test:
                var componentUnderTest = new MyComponent();

                // Act:
                int year = componentUnderTest.GetTheCurrentYear();

                // Assert: 
                // This will always be true if the component is working:
                Assert.AreEqual(fixedYear, year);
            }
        }
}
用于能够对不在您控制下的系统或其他组件进行单元测试

[TestClass]
public class TestClass1
{ 
        [TestMethod]
        public void TestCurrentYear()
        {
            int fixedYear = 2000;

            // Shims can be used only in a ShimsContext:
            using (ShimsContext.Create())
            {
                // Arrange:
                // Shim DateTime.Now to return a fixed date:
                System.Fakes.ShimDateTime.NowGet = 
                () =>
                { return new DateTime(fixedYear, 1, 1); };

                // Instantiate the component under test:
                var componentUnderTest = new MyComponent();

                // Act:
                int year = componentUnderTest.GetTheCurrentYear();

                // Assert: 
                // This will always be true if the component is working:
                Assert.AreEqual(fixedYear, year);
            }
        }
}

您要抽象的是
DateTime。现在
函数不是
DateTime
数据类型,您可以保持实现完全相同,但只需修复类型即可

public interface ITimeProvider
{
    DateTime Now { get; }
    string ToShortDateString();
}

public class DateTimeProvider : ITimeProvider
{

    public DateTime Now
    {
        get { return DateTime.Now; }
    }

    public string ToShortDateString()
    {
        return Now.ToShortDateString();
    }
}


public class RemoteTimeProvider : ITimeProvider
{
    public DateTime Now
    {
        get 
        { 
            using(var client = new WebClient())
            {
                var timeString = client.DownloadString(http://www.timeapi.org/utc/now);
                return DateTime.Parse(timeString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime()
            }

        }
    }

    public  DateTimeProvider()
    {

    }
    public string ToShortDateString()
    {
        //ToDo
    }
}

另外,我并没有真正理解您的
ToSortDateString()
的功能,它不接受参数,只使用从
new DateTime()
返回的值。您抽象的是
DateTime。现在
函数不是
DateTime
数据类型,您可以保持实现完全相同,但只需修复类型

public interface ITimeProvider
{
    DateTime Now { get; }
    string ToShortDateString();
}

public class DateTimeProvider : ITimeProvider
{

    public DateTime Now
    {
        get { return DateTime.Now; }
    }

    public string ToShortDateString()
    {
        return Now.ToShortDateString();
    }
}


public class RemoteTimeProvider : ITimeProvider
{
    public DateTime Now
    {
        get 
        { 
            using(var client = new WebClient())
            {
                var timeString = client.DownloadString(http://www.timeapi.org/utc/now);
                return DateTime.Parse(timeString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime()
            }

        }
    }

    public  DateTimeProvider()
    {

    }
    public string ToShortDateString()
    {
        //ToDo
    }
}

另外,我并没有真正理解您的
toSortDateString()
的功能,它不接受参数,只使用从
new DateTime()
返回的值,但我遇到了一些问题。“不起作用,因为我没有指定类型”,但您已使用我假定的注入容器注册了接口的实现?“但这样我就无法使用其他timeprovider”–您考虑使用与
DateTime
不同的类型来表示日期和时间的可能性有多大?事实并非如此,但我确实想模拟它进行测试。您只需要能够模拟
DateTime。现在
进行测试(您与该时间提供者在一起)。没有理由封装整个
DateTime
类型;您可以按照测试所需的方式创建datetime对象。@Sumsar1812-您能解释一下为什么需要
datetime
作为泛型类型参数吗?“但我遇到了一些问题”。“不起作用,因为我没有指定类型”,但您已使用我假定的注入容器注册了接口的实现?“但这样我就无法使用其他timeprovider”–您考虑使用与
DateTime
不同的类型来表示日期和时间的可能性有多大?事实并非如此,但我确实想模拟它进行测试。您只需要能够模拟
DateTime。现在
进行测试(您与该时间提供者在一起)。没有理由封装整个
DateTime
类型;您可以按照测试所需的方式创建datetime对象。@Sumsar1812-您能解释一下为什么需要
datetime
作为泛型类型参数吗?