public void DoSomethingAccordingToYear()
{
if(DateTime.Now.Year < 2010)
DoSomething();
else
DoSomethingElse();
}
I want to test this method. How can I mock DateTime without changing my code and without using interfaces?
public void DoSomethingAccordingToYear()
{
if(DateTime.Now.Year < 2010)
DoSomething();
else
DoSomethingElse();
}
I want to test this method. How can I mock DateTime without changing my code and without using interfaces?
One common way to do this is to pass in a component that gets the date. For example:
public interface IDateTimeNowProvider
{
DateTime Now { get; }
}
public class DateTimeNowProvider : IDateTimeNowProvider
{
public DateTime Now => DateTime.Now;
}
Now you can inject a IDateTimeNowProvider
into your object and mock that instead.
If you change the definition of your method it would be simple:
public void DoSomethingAccordingToYear(DateTime testDate)
{
if(testDate.Year < 2010)
DoSomething();
else
DoSomethingElse();
}
Then call it like this:
// production
DoSomethingAccordingToYear(DateTime.Now);
// test
DoSomethingAccordingToYear(new DateTime(2009,1,1));
EDIT
If you don't want to change the way you call the method, you could also implement it like this:
public void DoSomethingAccordingToYear(DateTime? testDate = null)
{
testDate = testDate ?? DateTime.Now;
if (testDate.Year < 2010)
DoSomething();
else
DoSomethingElse();
}
If you would call it without a parameter then it would use DateTime.Now
but you can still pass a parameter for testing.