Writing tests for code that deals with time is always tricky, and Ayende’s solution is probably the most elegant around. There’s always room for some syntactic sugar though!
using System;
using NUnit.Framework;
namespace Your.Namespace.Here
{
public class SystemTime : IDisposable
{
private static readonly Func<DateTime> GetDateTimeNow = () => DateTime.Now;
private static readonly Func<DateTime> GetUtcNow = () => DateTime.UtcNow;
public static Func<DateTime> Now = GetDateTimeNow;
public static Func<DateTime> UtcNow = GetUtcNow;
public static void Reset()
{
Now = GetDateTimeNow;
UtcNow = GetUtcNow;
}
private SystemTime(DateTime now)
{
Now = () => now;
}
public void Dispose()
{
Reset();
}
public static SystemTime Is(DateTime dateTime)
{
return new SystemTime(dateTime);
}
}
public class Examples
{
[Test]
public void Change_time()
{
var bohemiaAdoptsTheGregorianCalendar = new DateTime(1584, 1, 17);
using(SystemTime.Is(bohemiaAdoptsTheGregorianCalendar))
{
Assert.That(SystemTime.Now(), Is.EqualTo(bohemiaAdoptsTheGregorianCalendar));
// do something
}
Assert.That(SystemTime.Now(), Is.EqualTo(DateTime.Now));
}
}
}
And yes, I do like using dates from history :)
One thought on “Stop… system time!”