在单元测试中处理DateTime.Now的策略 [英] Strategies for dealing with DateTime.Now in unit tests

查看:61
本文介绍了在单元测试中处理DateTime.Now的策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的业务逻辑在星期六或星期日不执行某些功能。我希望我的单元测试能够验证是否执行了这些功能,但是测试将在周六/周日失败。

I have business logic that does not perform certain functions on Saturday or Sunday. I want my unit tests to verify that these functions are performed, but the tests will fail on Saturday/Sunday.

我认为最简单的方法是传递单元测试友好的消息,指出如果在星期六/星期日运行测试结果,则该测试结果无效。

I figure the easiest route is to have the unit tests convey a friendly message stating that the test results are not valid if they are run on Saturday/Sunday.

使用C#/ NUnit ...

With C# / NUnit...

Assert.That(
  DateTime.Now.DayOfWeek != DayOfWeek.Sunday && DateTime.Now.DayOfWeek !=      
  DayOfWeek.Saturday, "This test cannot be run on Saturday or Sunday");

是否可以/建议尝试模拟日期?

Is it possible/advisable to try and mock the date? Are there other strategies for handling this scenario?

推荐答案


是否有可能/建议尝试模拟?日期?

Is it possible/advisable to try and mock the date?

是的,不仅建议这样做,而且还是唯一可靠地对代码进行单元测试的方法。假设您想测试以下(无意义的)方法:

Yes, not only that it is advisable but it is the only way to reliably unit test your code in isolation. Suppose that you wanted to test the following (meaningless) method:

public bool Foo()
{
    return (DateTime.Now.DayOfWeek == DayOfWeek.Sunday);
}

很明显您无法测试它,因为它依赖于静态方法(更精确的是静态现在属性)。显然,像这样紧密耦合的组件不能单独进行单元测试。

It's more than obvious that you can't test it because it relies on a static method (the static Now property to be more precise). It's clear that components which are tightly coupled like this cannot be unit tested in isolation.

现在考虑这种改进(用构造函数DI分离关注点):

Now consider this improvement (separation of concerns with constructor DI):

private readonly Func<DateTime> _nowProvider;
public SomeClass(Func<DateTime> nowProvider)
{
    _nowProvider = nowProvider;
}

public bool Foo()
{
    return (_nowProvider().DayOfWeek == DayOfWeek.Sunday);
}

现在,单元测试变得更好,更容易。 SomeClass 不再取决于不确定的日期。在实际的应用程序中,您显然会实例化 SomeClass

Now that's much better and easier to unit test. SomeClass no longer depends on a non-deterministic date. In the real application you would obviously instantiate SomeClass like this:

var s = new SomeClass(() => DateTime.Now);
s.Foo();

在单元测试中,您将对其进行模拟,以便可以验证两种情况:

and in your unit test you will mock it so that you can verify both cases:

var subjectUnderTest = new SomeClass(() => new DateTime(2011, 1, 3));
var actual = subjectUnderTest.Foo();
// assertions, ...

这篇关于在单元测试中处理DateTime.Now的策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆