Strategies for dealing with DateTime.Now in unit tests

前端 未结 2 1167
说谎
说谎 2021-01-19 02:58

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 f

2条回答
  •  半阙折子戏
    2021-01-19 03:37

    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.

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

    private readonly Func _nowProvider;
    public SomeClass(Func nowProvider)
    {
        _nowProvider = nowProvider;
    }
    
    public bool Foo()
    {
        return (_nowProvider().DayOfWeek == DayOfWeek.Sunday);
    }
    

    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, ...
    

提交回复
热议问题