Thursday, October 17, 2013

Unit Testing DateTime.Now or DateTime.UtcNow

TDD is a great methodology, and if you follow it properly and get fanatic about it, then you eventually look for time to refactor all your code to be properly designed - hence - testable.
Eventually, you'll come up to a code where you've used DateTime.Now or DateTime.UtcNow properties, and start to think, should you really need to test this minor bit? The answer will be "Absolutely YES". But then, does it worth it to refactor the code for this simple thing?
If you're lazy enough and would be happy to solve the problem with some minor risk, then the following technique will be for you.
Let's say you want to test the following code - the Save() method:

internal class SampleState
{
    public DateTime LastSaved {get; set;}

    public void Save()
    {
          this.LastSaved = DateTime.UtcNow;
    }
}

The proper way would be to mock out the date/time provider and refer to it in the code. Alternatively this simple technique will be helpful:

[TestMethod]
public void Save_SetsLastSavedTime()
{
    // Setup
    SampleState sut = new SampleState();
    DateTime beforeCall = DateTime.UtcNow;

    // Act
    sut.Save();

    DateTime afterCall = DateTime.UtcNow;

    // Validate
    Assert.IsTrue(sut.LastSaved >= beforeCall && sut.LastSaved <= afterCall);   
}

The technique insures, that the time saved is within the test interval between the call started and ended. As mentioned before - this is not an explicit verification, but still - it gives high confidence that the proper time is being set.

Hope this will be useful !