Abstract DateTime

DateTime is part of the .NET Framework, and therefore, it should be abstracted away from our system. Typically, we want our system to depend on interfaces, allowing us to substitute implementations at runtime.

Following is an example of ITimeManager:

public interface ITimeManager
{
DateTime Now { get; }
}

For testing purposes, you might end up with an implementation of ITimeManager that looks like this:

public class TestTimeManager : ITimeManager
{
public Func<DateTime> CurrentTime = () => DateTime.Now;

public void SetDateTime(DateTime now)
{
CurrentTime = () => now;
}

public DateTime Now => CurrentTime();
}

This allows us to set the value for Now so that we can supply a known value to our test methods. Now, let's revisit our tests:

[Theory]
[InlineData(12)]
[InlineData(13)]
[InlineData(14)]
[InlineData(15)]
[InlineData(16)]
[InlineData(17)]
[InlineData(18)]
[InlineData(19)]
[InlineData(20)]
[InlineData(21)]
[InlineData(22)]
[InlineData(23)]
public void GivenAfternoon_ThenAfternoonMessage(int hour)
{
// Arrange
var afternoonTime = new TestTimeManager();
afternoonTime.SetDateTime(new DateTime(2017, 7, 13, hour, 0, 0));
var messageUtility = new MessageUtility(afternoonTime);

// Act
var message = messageUtility.GetGreeting();

// Assert
Assert.Equal("Good afternoon", message);
}

[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(2)]
[InlineData(3)]
[InlineData(4)]
[InlineData(5)]
[InlineData(6)]
[InlineData(7)]
[InlineData(8)]
[InlineData(9)]
[InlineData(10)]
[InlineData(11)]
public void GivenMorning_ThenMorningMessage(int hour)
{
// Arrange
var morningTime = new TestTimeManager();
morningTime.SetDateTime(new DateTime(2017, 7, 13, hour, 0, 0));
var messageUtility = new MessageUtility(morningTime);

// Act
var message = messageUtility.GetGreeting();

// Assert
Assert.Equal("Good morning", message);
}

Our production code would end up looking something like this:

public class MessageUtility
{
private readonly ITimeManager _timeManager;

public MessageUtility(ITimeManager timeManager)
{
_timeManager = timeManager;
}

public string GetMessage()
{
if (_timeManager.Now.Hour < 12)
return "Good morning";

return "Good afternoon";
}
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.20.231