Testing DateTime.Now
Monday, February 1st, 2010
When you are doing Test Driven Development (TDD) many time during the testing phase you’ll find yourself with a code that depends on current time.
It’s not possible write tests for this code as DateTime.Now changes constantly.
Let’s take a look at following method:
public string CreateName(...)
{
return "name " + DateTime.Now;
}
The solution to this problem is simple. We’ll introduce Clock class with the same interface as DateTime:
public string CreateName(...)
{
return "name " + Clock.Now;
}
We’d like the test to look something like this:
[Test]
public void CreateName_AddsCurrentTimeAtEnd()
{
using (Clock.NowIs(new DateTime(2010, 12, 31, 23, 59, 00)))
{
string name = new ReportNameService().CreateName(...);
Assert.AreEqual("name 2010-12-31 23:59:00", name);
}
}
Tests should not leave any side effects. This is why we are using IDisposable pattern. After text execution Clock.Now is reverted and again returns current time.
Finally this is how Clock class looks like:
public class Clock : IDisposable
{
private static DateTime? _nowForTest;
public static DateTime Now
{
get { return _nowForTest ?? DateTime.Now; }
}
public static IDisposable NowIs(DateTime dateTime)
{
_nowForTest = dateTime;
return new Clock();
}
public void Dispose()
{
_nowForTest = null;
}
};




