问题描述
我有一些(C#)代码依赖于今天的日期来正确计算未来的事情。如果我在测试中使用今天的日期,我必须在测试中重复计算,这不太正确。在测试中将日期设置为已知值的最佳方式是什么,以便我可以测试结果是已知值?
我喜欢使用时间实际上依赖于接口的类,例如
interface IClock
{
DateTime Now {get;
}
具体实现
$ pre> $ code class SystemClock:IClock
{
DateTime Now {get {return DateTime.Now; }}
}
然后如果你愿意,你可以提供任何其他种类的时钟想要测试,如
class StaticClock:IClock
{
DateTime Now {get {return new DateTime(2008,09,3,9,6,13); }}
}
可能有一些开销为依赖的类提供时钟但是可以通过任何数量的依赖注入解决方案来处理(使用控制的反转容器,普通的旧构造函数/ setter注入,甚至是一个)。
提供提供所需时间的对象或方法的其他机制也起作用,但我认为关键是避免重置系统时钟,因为这将导致其他级别的痛苦。
此外,使用 DateTime.Now
并将其包含在您的计算中不仅不感到正确 - 它会剥夺您测试特定时间的能力,例如,如果您发现只发生在午夜边界附近或周二的错误。使用当前时间将不允许您测试这些场景。或者至少不要随便你。
I've got some (C#) code that relies on today's date to correctly calculate things in the future. If I use today's date in the testing, I have to repeat the calculation in the test, which doesn't feel right. What's the best way to set the date to a known value within the test so that I can test that the result is a known value?
My preference is to have classes that use time actually rely on an interface, such as
interface IClock
{
DateTime Now { get; }
}
With a concrete implementation
class SystemClock: IClock
{
DateTime Now { get { return DateTime.Now; } }
}
Then if you want, you can provide any other kind of clock you want for testing, such as
class StaticClock: IClock
{
DateTime Now { get { return new DateTime(2008, 09, 3, 9, 6, 13); } }
}
There may be some overhead in providing the clock to the class that relies on it, but that could be handled by any number of dependency injection solutions (using an Inversion of Control container, plain old constructor/setter injection, or even a Static Gateway Pattern).
Other mechanisms of delivering an object or method that provides desired times also work, but I think the key thing is to avoid resetting the system clock, as that's just going to introduce pain on other levels.
Also, using DateTime.Now
and including it in your calculations doesn't just not feel right - it robs you of the ability to test particular times, for example if you discover a bug that only happens near a midnight boundary, or on Tuesdays. Using the current time won't allow you to test those scenarios. Or at least not whenever you want.
这篇关于在测试期间覆盖DateTime.Now的好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!