Helper class that will return DateTime.Now, but can be changed to deal with tests.
---
title: Dealing with Dotnet DateTime in Tests
subtitle: Helper class that will return DateTime.Now, but can be changed to deal with tests.
author: Ayende Rahien
date: July 7, 2008
source: https://ayende.com/blog/3408/dealing-with-time-in-tests
notoc: false
---
One of the more annoying things to test is time sensitive code.
I just spent five minutes trying to figure out why this code if failing:
```csharp
repository.ResetFailures(failedMsgs);
var msgs = repository.GetAllReadyMessages();
Assert.AreEqual(2, msgs.Length);
```
Reset failures will set the retry time of the failed messages to 2 seconds in
the features. GetAllReadyMessages will only get messages that are ready now.
Trying to test that can be a real pain. One solution that I have adopted across
all my projects is introducing a separate concept of time:
> `SystemDateTime.cs` example from [dotnetcore.samples](https://github.com/cmendible/dotnetcore.samples/blob/master/remove.datetime.dependency.test/SystemDateTime.cs) on Github.
```csharp
namespace MyServices
{
using System;
/// <summary>
/// Helper class that will return DateTime.Now, but can be changed to deal with tests.
/// https://ayende.com/blog/3408/dealing-with-time-in-tests
/// </summary>
public static class SystemDateTime
{
/// <summary>
/// Gets a function that when evaluated returns a local date and time.
/// </summary>
/// <returns>A function that when evaluated returns a local date and time.</returns>
public static Func<DateTime> Now = () => DateTime.Now;
}
}
```
Now, instead of calling DateTime.Now, I make the call to `SystemDateTime.Now()`, and
get the same thing. This means that I can now test the code above easily, using:
```csharp
SystemDateTime.Now = () => new DateTime(2000,1,1);
repository.ResetFailures(failedMsgs);
SystemDateTime.Now = () => new DateTime(2000,1,2);
var msgs = repository.GetAllReadyMessages();
Assert.AreEqual(2, msgs.Length);
```
### Example Service
> `TimeDependentService.cs` example from [dotnetcore.samples](https://github.com/cmendible/dotnetcore.samples/blob/master/remove.datetime.dependency.test/TimeDependentService.cs) on Github.
```cs
namespace MyServices
{
using System;
/// <summary>
/// A time dependent on DateTime.Now
/// </summary>
public class TimeDependentService
{
/// <summary>
/// Tells if it's morning.
/// </summary>
/// <returns>true if it's before 12</returns>
public bool OldIsMorning()
{
return DateTime.Now.Hour < 12;
}
/// <summary>
/// Tells if it's morning using the helper by Ayende.
/// </summary>
/// <returns>true if it's before 12</returns>
public bool IsMorning()
{
return SystemDateTime.Now().Hour < 12;
}
}
}
```
### Example Tests
> `Tests.cs` example from [dotnetcore.samples](https://github.com/cmendible/dotnetcore.samples/blob/master/remove.datetime.dependency.test/Tests.cs) on Github.
```cs
namespace Tests
{
using System;
using MyServices;
using Xunit;
public class Tests
{
/// <summary>
/// If this test is run after noon it will fail cause of the dependency on the system time.
/// </summary>
[Fact]
public void Will_Fail_After_Noon()
{
var svc = new TimeDependentService();
Assert.True(svc.OldIsMorning());
}
/// <summary>
/// This test will run OK no matter the systems time, cause we are using the Ayende
/// approach to tests with time dependencies.
/// </summary>
[Fact]
public void Will_Run_OK_No_Matter_The_Real_Time()
{
// Force the time to 11 AM
SystemDateTime.Now = () => new DateTime(2016, 10, 10, 11, 0, 0);
var svc = new TimeDependentService();
Assert.True(svc.IsMorning());
}
}
}
```
This is a really painless way to deal with this issue.