I’ve always been a fan of the elegance of Ayende’s SystemTime approach to dealing with time in tests. Unfortunately, I’ve recently re-discovered the problems that come with using globals.
I had a dependency on two different projects, each of which declared their own instance of SystemTime. Not insurmountable, as they were namespaced, but annoying and confusing nonetheless.
So from now on, for me, the new One True Way is just to pass in a Func<DateTime> as a constructor dependency:
public class Frobulator { public Frobulator(Func<DateTime> currentTime) { this.currentTime = currentTime; } public DateTime Frobulate() { return currentTime(); } } [TestFixture] public class FrobulatorTests { [Test] public void Frobulator_should_use_current_time() { var juanRodriguezCabrilloDiscoversCaliforniaAtSanDiegoBay = new DateTime(1542, 9, 28); var frobulator = new Frobulator(() => juanRodriguezCabrilloDiscoversCaliforniaAtSanDiegoBay); var dateTime = frobulator.Frobulate(); Assert.That(dateTime, Is.EqualTo(juanRodriguezCabrilloDiscoversCaliforniaAtSanDiegoBay)); } }
Hi Graham,
how about Property-Injection with default Func instead. This way you have the desired default behaviour without effort, yet being able to change it when testing.
Cheers,
Khalid