Unit Testing: Testing methods that rely on DateTime.Now

I have a class whose behavior depends on the time of day. It called DateTime.Now directly to get the current time. Doing it this way makes it difficult to write tests to prove that all use cases work as expected.

One simple solution is to add a delegate called Now to the class. By default it points to an anonymous method which returns DateTime.Now:

public Func<DateTime> Now = () => DateTime.Now;

I replaced all references of DateTime.Now with Now(). The class behaves exactly as it did before.

The neat thing is that during testing now, I have complete control over the Date and Time. After creation of the class, I can change the behavior of Now(). For example, I can set it to a static date:

var myClass = new MyClass();
myClass.Now = () => DateTime.Parse("1/10/2011 8:00am");
or even create a sequence of dates:

var dates = new Queue<DateTime>();
dates.Enqueue(DateTime.Parse("1/1/2011 5:00pm");
dates.Enqueue(DateTime.Parse("1/1/2011 6:00pm");
dates.Enqueue(DateTime.Parse("1/2/2011 5:00pm");
 
myClass.Now = () => dates.Dequeue();