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
  • 169
  • 2
  • 13

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
  • 104,599
  • 10
  • 205
  • 202
2

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,735
  • 4
  • 32
  • 52