简体   繁体   English

单元测试代码取决于DateTime.Now

[英]Unit testing code dependent on DateTime.Now

The Codewars.com description below. 下面的Codewars.com说明。

Create a function which passes in a birthday and returns how old a person is in years. 创建一个函数,该函数传递生日并返回一个人的年龄。

The Test Cases have already been developed for you. 测试用例已经为您开发。 When the test case was created the programmer assumed there would be a shared interface between a SystemClock class and StaticClock class. 当创建测试用例时,程序员假定在SystemClock类和StaticClock类之间将存在一个共享接口。

public class SystemClock : IClock { ... }

public class StaticClock : IClock { ... }

The SystemClock class needs to implement a DateTime method that returns DateTime.Now SystemClock类需要实现一个DateTime方法,该方法返回DateTime.Now

The StaticClock method needs to implement a DateTime method that returns a DateTime value that was passed to its constructor. StaticClock方法需要实现一个DateTime方法,该方法返回传递给其构造函数的DateTime值。

The StaticClock implementation of IClock is used in our UnitTest to provide a constant time value for our unittest. IClockStaticClock实现在我们的UnitTest中使用,以为我们的unittest提供恒定的时间值。 Considering that time is always in motion...if we were to simply create unit test based on DateTime.Now then our unit test will fail over time. 考虑到时间总是在动...如果我们只是基于DateTime.Now创建单元测试,那么现在我们的单元测试将随着时间而失败。

With the StaticClock we can inject what value our IClock.Now method should return so our unit test will continue to pass even as time moves on. 使用StaticClock我们可以注入IClock.Now方法返回的值,因此即使时间流逝,我们的单元测试也将继续通过。

My code below. 我的代码如下。

using System;

namespace AgeFromDOB
{
    public class Program
    {

        public class Kata 
        {
            private DateTime staticClock;

            public Kata(StaticClock staticClock)
            {
                this.staticClock = staticClock.Now;
            }

            public int GetAgeFromDOB(DateTime birthday)
            {
                return staticClock.Year - birthday.Year;
            }
        }

        public interface IClock
        {
            DateTime Now { get; }
        }

        public class SystemClock : IClock
        {
            public DateTime Now { get; }

            public  DateTime Method(DateTime Now)
            {
                return Now;
            }
        }

        public class StaticClock : SystemClock, IClock
        {
            public StaticClock(DateTime Now)
            {
                 Method(Now);
            }
        }

        static void Main(string[] args)
        {
            Kata kata;
            kata = new Kata(new StaticClock(new DateTime(2008,09,3)));
            kata.GetAgeFromDOB(new DateTime(1984,04,23));
            Console.ReadKey();
        }
    }
}

when I try to pass in new Kata(new StaticClock(new DateTime(2008,09,3))); 当我尝试传递new Kata(new StaticClock(new DateTime(2008,09,3)));

the object is not being passed correctly and I keep getting the wrong outcome. 该对象未正确传递,我一直得到错误的结果。

I would like to know where to research or what pattern I should look at to solve this problem ? 我想知道在哪里进行研究或应该考虑采用哪种模式来解决此问题?

Kata is dependent on an implementation concretion when it should be dependent on an abstraction. Kata应该依赖抽象时,它依赖于实现实现。 That would allow Kata the flexibility at accept different implementations of the abstraction. 这将使Kata灵活地接受抽象的不同实现。

public class Kata {
    private readonly IClock clock;

    public Kata(IClock clock) {
        this.clock = clock;
    }

    public int GetAgeFromDOB(DateTime birthday) {
        var now = clock.Now;    
        var age = now.Year - birthday.Year;
        if (birthday > now.AddYears(-age)) age--;
        return age;
    }
}

public interface IClock {
    DateTime Now { get; }
}

The two implementations of IClock can be kept simple based on the requirements stated in the question. 根据问题中所述的要求,可以使IClock的两种实现保持简单。

The SystemClock class needs to implement a DateTime method that returns DateTime.Now SystemClock类需要实现一个DateTime方法,该方法返回DateTime.Now

public class SystemClock : IClock {
    public DateTime Now { get { return DateTime.Now; } }
}

The StaticClock method needs to implement a DateTime method that returns a DateTime value that was passed to its constructor. StaticClock方法需要实现一个DateTime方法,该方法返回传递给其构造函数的DateTime值。

public class StaticClock : IClock {
    public StaticClock(DateTime now) {
         this.Now = now;
    }

    public DateTime Now { get; private set; }
}

Which should allow you to get the desired results. 应该可以让您获得理想的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM