Unit Testing Time
Date Published: 07 July 2008
Oren has a post showing how he deals with time sensitive code in his unit tests. One thing that’s interesting is that, like my previous post, deals with the System.Func
[TestMethod]
public void TimeDependency()
{
myCache.Insert(myKey, myValue, cacheSeconds);
Assert.AreEqual(myValue, myCache[myKey], "Value removed immediately - should still be there.");
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, cacheSeconds).Add(TimeSpan.FromMilliseconds(500)));
Assert.IsNull(myCache[myKey], "Value should be expired from cache at this point.");
}
Any time you’re having to put Thread.Sleep() in your unit test, that’s a big sign something’s wrong.
To correct this, what I have done in the past is define a Context.ServerTime property of type DateTime which I can set, but which defaults to DateTime.Now(). However, Oren’s technique of actually using a delegate for the time, which can be replaced with either a static value or a new method for computing the current time, seems like a definite improvement (and looks like this):
public static class SystemTime
{
public static Func<DateTime> Now = () => DateTime.Now;
}
With this code in place, changing the definition of “now” in a unit test involves simply one line of code:
SystemTime.Now = () => new DateTime(2008,1,1);
The () => syntax is simply a parameterless delegate. I’m really loving these.
Category - Browse all categories
About Ardalis
Software Architect
Steve is an experienced software architect and trainer, focusing on code quality and Domain-Driven Design with .NET.