下面的Codewars.com说明。
创建一个传递生日的函数,并返回一个人多少年。
已经为您开发了测试用例。在创建测试用例时,程序员假设SystemClock
类和StaticClock
类之间存在共享接口。
public class SystemClock : IClock { ... }
public class StaticClock : IClock { ... }
SystemClock
类需要实现返回DateTime
的{{1}}方法
DateTime.Now
方法需要实现一个StaticClock
方法,该方法返回传递给其构造函数的DateTime
值。
我们的UnitTest使用DateTime
StaticClock
实现来为我们的unittest提供一个恒定的时间值。考虑到时间总是在运动......如果我们只是根据IClock
创建单元测试,那么我们的单元测试会随着时间的推移而失败。
使用DateTime.Now
,我们可以注入我们的StaticClock
方法应该返回的值,这样即使时间继续,我们的单元测试也会继续通过。
我的代码如下。
IClock.Now
当我尝试传入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();
}
}
}
对象没有正确传递,我一直得到错误的结果。
我想知道在哪里研究或者我应该考虑解决这个问题的模式?
答案 0 :(得分:2)
Kata
依赖于实现具体性,因为它应该依赖于抽象。这将允许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; }
}
IClock
的两个实现可以根据问题中的要求保持简单。
SystemClock类需要实现一个返回DateTime.Now
的DateTime方法
public class SystemClock : IClock {
public DateTime Now { get { return DateTime.Now; } }
}
StaticClock方法需要实现一个DateTime方法,该方法返回传递给其构造函数的DateTime值。
public class StaticClock : IClock {
public StaticClock(DateTime now) {
this.Now = now;
}
public DateTime Now { get; private set; }
}
这应该可以让您获得理想的结果。