Dealing with time in tests
One of the more annoying things to test is time sensitive code.
I just spent five minutes trying to figure out why this code if failing:
repository.ResetFailures(failedMsgs);
var msgs = repository.GetAllReadyMessages();
Assert.AreEqual(2, msgs.Length);
Reset failures will set the retry time of the failed messages to 2 seconds in the features. GetAllReadyMessages will only get messages that are ready now.
Trying to test that can be a real pain. One solution that I have adopted across all my projects is introducing a separate concept of time:
public static class SystemTime
{
public static Func<DateTime> Now = () => DateTime.Now;
}
Now, instead of calling DateTime.Now, I make the call to SystemTime.Now(), and get the same thing. This means that I can now test the code above easily, using:
SystemTime.Now = () => new DateTime(2000,1,1);
repository.ResetFailures(failedMsgs);
SystemTime.Now = () => new DateTime(2000,1,2);
var msgs = repository.GetAllReadyMessages();
Assert.AreEqual(2, msgs.Length);
This is a really painless way to deal with this issue.