I am following along with the TDD Kata 'Greeter', wherein I have to create a class with a method which returns a different output depending on the time of day it was called. So I have this class Greeter
public class Greeter : Greeter
{
public DateTime time
{
get
{
return DateTime.Now;
}
}
public Greeter() { }
public string greet(string name)
{
string greeting = "Hello ";
name = name.Substring(0, 1).ToUpper() + name.Substring(1);
if(name.Length > 36)
{
name = name.Substring(0, 35);
}
if(time.Hour >= 6 && time.Hour <= 12)
{
greeting = "Good morning";
} else if (time.Hour >= 18 && time.Hour <= 22)
{
greeting = "Good evening";
} else if (time.Hour >=22 || time.Hour < 6)
{
greeting = "Good night";
}
return $"{greeting} {name}";
}
}
Greeter
implements IGreeter
public interface IGreeter
{
DateTime time
{
get;
}
string greet(string name);
}
Now on the unit testing side of things, I have to test given different times of day to see the response: Good morning ~
in the AM, Good evening ~
in the evening, Good night ~
at night, and Hello ~
in the default case.
So my question is, how do I design these unit tests with these time constraints in mind without too much modifying of the class? From what I've been told, changing the class just to enable unit tests is considered code smell. Is there a way I can achieve this using NUnit and Moq? The best solution I've seen so far is to DI a time provider in the constructor, but I'd rather not have to supply the generic time provider in every instantiation just to enable the tests.
Any guidance would be greatly appreciated.