One of the things, that you might have seen in the code snippets around this blog, is usage of SystemUtil.Sleep and SystemUtil.Now instead of the Thread.Sleep and DateTime.Now here and then.
The reason for these replacements is simple – they make unit tests much easier to write and read. And, in the case of Sleep, they also allow tests run instantly (as opposed to adding seconds now and then). This results in the reduced development friction and a better Test Driven Development experience.
Since Lokad Libraries are all about sharing and reusing practices for efficient .NET development, that’s why we have SystemUtil there.
SystemUtil
SystemUtil features simple methods. Here are their signatures in C#:
// use instead of DateTime.Now
static DateTime Now { get; }
// use instead of the Thread.Sleep
static void Sleep()
// resets everything to the default
static void Reset()
// allows to provide custom overrides
static void SetDateTimeProvider(Func<DateTime> dateTimeProvider)
static void SetTime(DateTime time)
static void SetSleep(Action<TimeSpan> sleepRoutine)
SystemUtil.Sleep
Here’s how we can test the code that uses SystemUtil.Sleep instead of Thread.Sleep:
// Just to make sure that our test cleans up all
// overrides at the end
[TearDown]
public void TearDown()
{
SystemUtil.Reset();
}
[Test]
public void WaitAndRetry()
{
// provide our own Sleep override
// that will capture the amount of time slept
// instead of actually sleeping
TimeSpan slept = TimeSpan.Zero;
SystemUtil.SetSleep(span => slept += span);
// define the policy that waits and retries on
// Timeout exceptions
var policy = ActionPolicy
.Handle<TimeoutException>()
.WaitAndRetry(Range.Create(5, i => i.Seconds()));
// Execute the policy with non-handled exception
Expect<ArgumentException>(() => policy.Do(RaiseArgument));
// We should not have slept at all
Assert.AreEqual(TimeSpan.Zero, slept);
// Execute policy with the handled exception
Expect<TimeoutException>(() => policy.Do(RaiseTimeout));
// We should have slept 0+1+2+3+4 seconds
// before giving up
Assert.AreEqual(10.Seconds(), slept);
}
SystemUtil.Now
That’s a piece of C# code that tests the CircuitBreaker policy (the policy itself leverages SystemUtil.Now instead of DateTime.Now):
[Test]
public void CircuitBreaker()
{
var time = new DateTime(2008, 1, 1);
SystemUtil.SetTime(time);
var policy = ActionPolicy
.Handle<TimeoutException>()
.CircuitBreaker(1.Minutes(), 2);
// [skipped]
// Elapse and rearm
SystemUtil.SetTime(time.AddMinutes(1));
Expect<TimeoutException>(() => policy.Do(RaiseTimeout));
// Non-elapse and trigger
SystemUtil.SetTime(time.AddSeconds(119));
Expect<TimeoutException>(() => policy.Do(Nothing));
// Elapse and pass
SystemUtil.SetTime(time.AddMinutes(2));
policy.Do(Nothing);
}
Summary
SystemUtil is a simple helper class from the Shared Libraries that is supposed to be used instead of common DateTime.Now and Thread.Sleep calls.
This allows to develop code that has less is more testable (unit tests are simpler and introduce less development friction)
Note: unit tests featured above are for WaitAndRetry and CircuitBreaker Exception Handling Action Policies (that’s a light-weight Application Block from the same open-source library).