Search code examples
c#datetimesimulation

Simulating DateTime to test scheduled events


I want to simulate DateTime. Let's say I have list of actions to perform, and each action has a datetime field. When that dateTime comes, the action should be performed.

I can check the datetime with DateTime.Now, but how can I simulate DateTime? I mean If the current time is 2pm. And the action should run at 4pm, 5pm. Can I use a simulate current time to 4pm and the first action will be performed and an hour later the second action will be performed?


Solution

  • The simplest way to achieve this is to change your system clock to the 'test time', run the test, and then change back. That's pretty hacky and I don't really recommend it, but it will work.

    A better way will be to use an abstraction over DateTime.Now which will allow you to inject either a static value or manipulate the retrieved value for testing. Given that you want the test value to 'tick', rather than remain a static snapshot, it's going to be easiest to add a TimeSpan to 'now'.

    So add a application setting called 'offset' that can be parsed as a TimeSpan

    <appSettings>
        <add key="offset" value="00:00:00" />
    </appSettings>
    

    and then add this value to your DateTime.Now every time you retrieve it.

    public DateTime Time
    { 
        get 
        { 
            var offset = TimeSpan.Parse(ConfigurationManager.AppSettings["offset"]);
            return DateTime.Now + offset;
        }
    }
    

    To run this one hour and twenty minutes in the future you simply adjust the offset value

    <add key="offset" value="01:20:00" />
    

    Ideally you'd create an interface for a DateTime and implement dependency injection, but for your purpose - although that would be preferred - I suggest that the can of worms that this opens will create a world of confusion for you. This is simple and will work.