Blogtronica

Thoughts, ramblings and insights

netronica.io

Time based unit testing tip

How do you test something with time, and you don't want to inject an ITime, resulting in dependencies heavy code?

public string GetGreeting()  
    {
        var response = "Good " + (DateTime.Now.Hour < 12 ? "morning!" : "afternoon!");
        return response;
    }

Simple, use a functional delagate where you can replace the implementation.

public static class DateTimeProvider  
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

public class Worker  
{
    public string GetGreeting()
    {
        var response = "Good " + (DateTimeProvider.Now().Hour < 12 ? "morning!" : "afternoon!");
        return response;
    }
}

And now it is testable!

[Theory]
[InlineData("2060-10-1 00:00:00", "morning")]
[InlineData("2060-10-1 11:59:59", "morning")]
[InlineData("2060-10-1 12:00:00", "afternoon")]
public void TestGreeting(string forDate, string expect)  
{
    DateTimeProvider.Now = () => DateTime.Parse(forDate);
    var sut = new Worker();
    var greeting = sut.GetGreeting();
    Assert.Contains(expect, greeting);
}

Photo credit https://www.flickr.com/photos/guysie/3608442265