我有这种方法取决于当前日期。它检查今天是太阳,周一,周二还是周三,然后它给出了5天的交货时间。如果它是星期四,星期五或星期六那么它给出了6天的交货时间来解释周末。
private DateTime GetEstimatedArrivalDate()
{
DateTime estimatedDate;
if (DateTime.Now.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = DateTime.Now.Date.AddDays(6);
}
else
{
estimatedDate = DateTime.Now.Date.AddDays(5);
}
return estimatedDate;
}
实际估算逻辑更复杂。为了这个问题,我简化了它。我的问题是如何根据今天的日期为这样的事情编写单元测试?
答案 0 :(得分:19)
您需要将当前日期作为参数传递:
private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
DateTime estimatedDate;
if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = currentDate.AddDays(6);
}
else
{
estimatedDate = currentDate.AddDays(5);
}
return estimatedDate;
}
在实际代码中,您可以这样称呼它:
DateTime estimatedDate = GetEstimatedArrivalDate(DateTime.Now.Date);
然后你可以按如下方式测试它:
DateTime actual = GetEstimatedArrivalDate(new DateTime(2010, 2, 10));
DateTime expected = ...;
// etc...
请注意,这也修复了程序中潜在的错误,其中日期在连续调用DateTime.Now
之间发生变化。
答案 1 :(得分:10)
一般来说,您需要抽象获取界面背后的当前日期和时间的方法,例如:
public interface IDateTimeProvider
{
DateTime Now { get; }
}
真正的服务是:
public class DateTimeProvider: IDateTimeProvider
{
public DateTime Now
{
get
{
return DateTime.Now;
}
}
}
测试服务将是:
public class TestDateTimeProvider: IDateTimeProvider
{
private DateTime timeToProvide;
public TestDateTimeProvider(DateTime timeToProvide)
{
this.timeToProvide = timeToProvide;
}
public DateTime Now
{
get
{
return timeToProvide;
}
}
}
对于需要当前时间的服务,让他们将IDateTimeProvider作为依赖项。对于真实的东西,传递一个新的DateTimeProvider();当你是一个组件时,传入一个新的TestDateTimeProvider(timeToTestFor)。
答案 2 :(得分:3)
让您的课程采用IClock
参数(通过构造函数或属性)
interface IClock
{
DateTime Now { get; }
}
然后,您可以使用虚假实施进行测试
class FakeClock : IClock
{
DateTime Now { get; set }
}
并在其余时间实现真正的实施。
class SystemClock : IClock
{
DateTime Now { get { return DateTime.Now; } }
}
答案 3 :(得分:1)
我会给出有争议的答案,不要测试它。
逻辑是微不足道的,并且它没有依赖关系,我相信良好的代码覆盖率,但是当它增加复杂性而没有真正的收益时却不会。
答案 4 :(得分:0)
似乎有足够数量的案例你可以明确地测试它们。该方法取决于今天的日期,但输出仅取决于星期几,每个日期都有一周中的某一天。
答案 5 :(得分:0)
您可以传入一个在正常执行期间返回DateTime.Now的委托,然后在另一个返回固定日期的委托中的测试传递中传入,并根据该结果断言您的结果。
答案 6 :(得分:0)
这样做的一种“常见”方式是“伪造”当前系统日期(可以通过多种方式完成),然后在“已知”日期测试代码。
另一个有趣的方法是将您的实施略微改为:
private DateTime GetEstimatedArrivalDate()
{
return GetEstimatedArrivalDate(DateTime.Now);
}
private DateTime GetEstimatedArrivalDate(DateTime forDate)
{
DateTime estimatedDate;
if (forDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = forDate.Date.AddDays(6);
}
else
{
estimatedDate = forDate.Date.AddDays(5);
}
return estimatedDate;
}
然后使用带参数的方法测试“立即”日期。
答案 7 :(得分:0)
我建议将其作为Mark suggests执行此操作,但添加了一个生成使用的重载调用,该调用不使用任何参数并使用DateTime.Now
private DateTime GetEstimatedArrivalDate()
{
return GetEstimatedArrivalDate(DateTime.Now);
}
private DateTime GetEstimatedArrivalDate(DateTime currentDate)
{
DateTime estimatedDate;
if (currentDate.DayOfWeek >= DayOfWeek.Thursday)
{
estimatedDate = currentDate.AddDays(6);
}
else
{
estimatedDate = currentDate.AddDays(5);
}
return estimatedDate;
}