0
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?

HilaB
  • 179
  • 2
  • 14

2 Answers2

4

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.

DavidG
  • 113,891
  • 12
  • 217
  • 223
3

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.

Romano Zumbé
  • 7,893
  • 4
  • 33
  • 55