beaucrawford.net

Give me data or give me death

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Don't show

Authors

Tags

Don't show

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010

    CoreDateTime.Now - The Future is Now

    Like most developers, I often find myself dealing with code that references DateTime.Now. For example consider this code that retrieves items relative to the current date/time:

    var command = new SqlCommand();
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "GetItems";
    command.Parameters.Add(new SqlParameter("TargetDate", DateTime.Now));

    It would be hard to develop an integration test for this code since it references DateTime.Now. What if I wanted to test the scenario where items with a future date/time value needed to be retrieved, i.e. how will the system behave six months from now? A simple, but very effective, way to deal with this is to add the following class:

    public class CoreDateTime
    {
        static CoreDateTime()
        {
            Executor = () => DateTime.Now;
        }
    
        internal static Func Executor
        {
            get;
            set;
        }
    
        public static DateTime Now
        {
            get
            {
                return Executor();
            }
        }
    }

    The key thing to note here is that the "Executor" property is simply a Func that wraps a call to the normal DateTime.Now. This means that CoreDateTime.Now will behave exactly like DateTime.Now.

    You will also notice that the "Executor" property uses the internal access modifier. This allows testing assemblies to inject a Func of their choosing. You can expose this property to test assemblies using the System.Runtime.CompilerServices.InternalsVisibleTo assembly attribute and then update it with code like:

    CoreDateTime.Executor = () => DateTime.Parse("5/10/2013 10:15 AM");

    You can also have successive calls to CoreDateTime.Now be evaluated against a fixed point in time. This allows you to easily jump to any point of time in the past or future. This code might look like:

    var init = DateTime.Now;
    CoreDateTime.Executor = () => dateTimePicker1.Value.AddSeconds((DateTime.Now - init).TotalSeconds);                

    Happy time travels!


    Categories: C# | Testing
    Posted by Beau on Saturday, June 27, 2009 10:13 AM
    Permalink | Comments (0) | Post RSSRSS comment feed

    Comments