aligneddev/unitTestingGettingStarted

Add SystemTime example

aligneddev opened this issue · 1 comments

Add links and code example of a testing seam for DateTime.

I've called this systemTime in the past.
Here's a possible implementation
using System;

namespace Shared.Core.Implementations
{
///


/// Testable alternative to DateTime.Now or DateTimeOffset.Now
///

public static class SystemTime
{
private static DateTime? _dateTimeHolder = null;

    /// <summary>
    /// Gets the current local DateTimeOffset
    /// </summary>
    public static DateTime Now => _dateTimeHolder ?? DateTime.Now;

    /// <summary>
    /// Allow overriding the time for testing
    /// </summary>
    /// <param name="fakeDateTime"></param>
    public static void SetNow(DateTime fakeDateTime)
    {
        _dateTimeHolder = fakeDateTime;
    }
    public static void ResetNow()
    {
        _dateTimeHolder = null;
    }

    private static DateTimeOffset? _offsetHolder = null;

    /// <summary>
    /// Gets the current local DateTimeOffset
    /// </summary>
    public static DateTimeOffset NowOffset => _offsetHolder ?? DateTimeOffset.Now;

    /// <summary>
    /// Allow overriding the time for testing
    /// </summary>
    /// <param name="fakeDateTimeOffset"></param>
    public static void SetNowOffset(DateTimeOffset fakeDateTimeOffset)
    {
        _offsetHolder = fakeDateTimeOffset;
    }

    public static void ResetOffsetNow()
    {
        _offsetHolder = null;
    }
}

}

Here's another option:
public class SystemTime
{
protected static Func localNow = () => DateTime.Now;
public static DateTime Now
{
get => localNow();
protected set { localNow = () => value; }
}
}

public class TestingSystemTime : SystemTime
{
public static DateTime StartForTest()
{
Now = DateTime.Now;
return Now;
}

    public static DateTime Reset()
    {
        localNow = () => DateTime.Now;
        return localNow();
    }

    public static DateTime AddMinutes(int mins)
    {
        Now = Now.AddMinutes(mins);
        return Now;
    }

    public static DateTime AddHours(int hours)
    {
        Now = Now.AddHours(hours);
        return Now;
    }
}