XUnit FreezeClock – Black Magic Stopping Time

The last few days I have been working on a small open source generic dictionary cache and writing unit tests to verify the cache was functioning correctly. I wanted to set a property that stored the DateTime an object was created and then make a comparison to the DateTime that was used when the property was set. Confusing…. Basically I needed to freeze time! I was just about to write a wrapper around the system clock when I thought it would be worth a quick check on Google to see if anyone had already tackled this problem already. I found that this was entirely possible to do by using XUnit. All that is needed is to add the FreezeClock attribute to a method, and then when you need to get the frozen DateTime you call Clock.Now. I was now able to make a comparison between the date and time when the property was set and the date and time that had been set (basically the same thing when your freeze time!). Please see the example usage below (I know I could have made this a lot easier by making comparisons on another type other than DateTime but this just seemed a whole lot more fun).

Example Usage

using Xunit;
            using System;
            using Xunit.Extensions;
            
            namespace Tribe.Cache.Test
            {
                public class CacheTests
                {
                    private readonly Cache _cache;
                    public CacheTests()
                    {
                         _cache = new Cache();
                    }
            
                    [Fact]
                    [FreezeClock(2010, 10, 01, 13, 00, 00)]
                    public void AnItemShouldBeAbleToBeAddedToTheCacheThenRetrieved()
                    {
                        _cache.Clear();
            
                        Phone phone = new Phone {CreatedAt = Clock.Now};
            

//adds an item to the cache if it does not already exist or has expired _cache.Get("__Phone", () => phone.ToString(), 5);
//create a new instance of phone Phone newPhone = new Phone { CreatedAt = DateTime.Now }; //this should retrieve the cached instance of phone as long as 5 seconds have not passed
string cachedItem = _cache.Get("__Phone", () => newPhone.ToString(), 5); Assert.Equal(Clock.Now.ToLongTimeString(), cachedItem); } internal class Phone { public DateTime CreatedAt { get; set; }
public override string ToString() { return CreatedAt.ToLongTimeString(); } } } }

To download Xunit please visit http://xunit.codeplex.com/
Tweet Me | Link To Facebook