My book contains a section on the Ambient Context pattern that uses a TimeProvider as an example. It's used like this:

this.closedAt = TimeProvider.Current.UtcNow;

Yesterday I was TDDing a state machine that consumes TimeProvider and needed to freeze and advance time at different places in the test. Always on the lookout for making unit tests more readable, I decided to have a little fun with literal extensions and TimeProvider. I ended up with this test:

// Fixture setup
var fixture = new WcfFixture();
var sut = fixture.CreateAnonymous<CircuitBreaker>();
// Exercise system
// Verify outcome
// Teardown

There are several items of note. Imagine that we can freeze time!


With the TimeProvider and an extension method, we can:

internal static void Freeze(this DateTime dt)
    var timeProviderStub = new Mock<TimeProvider>();
    timeProviderStub.SetupGet(tp => tp.UtcNow).Returns(dt);
    TimeProvider.Current = timeProviderStub.Object;

This effectively sets up the TimeProvider to always return the same time.

Later in the test I state that 2 minutes pass:


I particularly like the grammatically correct English. This is accomplished with a combination of a literal extension and changing the state of TimeProvider.

First, the literal extension:

internal static TimeSpan Minutes(this int m)
    return TimeSpan.FromMinutes(m);

Given the TimeSpan returned from the Minutes method, I can now invoke the Pass extension method:

internal static void Pass(this TimeSpan ts)
    var previousTime = TimeProvider.Current.UtcNow;
    (previousTime + ts).Freeze();

Note that I just add the TimeSpan to the current time and invoke the Freeze extension method with the new value.

Last, but not least, I should point out that the PutInOpenState method isn't some smelly test-specific method on the SUT, but rather yet another extension method.

Wish to comment?

You can add a comment to this post by sending me a pull request. Alternatively, you can discuss this post on Twitter or Google Plus, or somewhere else with a permalink. Ping me with the link, and I may add it as a comment.


Tuesday, 27 April 2010 04:24:25 UTC


"Our team wholeheartedly endorses Mark. His expert service provides tremendous value."
Hire me!