Kash Farooq's software development blog

.NET Developer

How to test DateTime.Now

Posted by Kash Farooq on June 17, 2012

A colleague new to TDD asked me how to do this recently, so I thought I’d blog it.

Here is some code we want to bring under test:

public void SomeMethodToBeTested()
{
  var dateTimeNow = DateTime.Now;
  if (dateTimeNow.Month == 4 && dateTimeNow.Day == 6)
  {
    //do something for the new tax year.
  }
  else
  {
    //do something for the current tax year.
  }
}

The problem is: how can we test different dates so make sure the correct tax year dependent processing takes place? We clearly need the ability to control the date being used. We could do this by creating a wrapper class for DateTime, but I prefer in this simple case to just use a Func.

The test code becomes:

[TestFixture]
public class StubbingDateTimeNowTest
{
  [Test]
  public void TestNewTaxTear()
  {
    var stubbingDateTimeNow=new StubbingDateTimeNow(() => new DateTime(2012,4,6)); //send in a Func to return the date I want to test
    stubbingDateTimeNow.SomeMethodNowTested();
    //Asserts to check correct processing took place
  }

  [Test]
  public void TestCurrentTaxTear()
  {
    var stubbingDateTimeNow=new StubbingDateTimeNow(() => new DateTime(2012,3,6)); //send in a Func to return the date I want to test
    stubbingDateTimeNow.SomeMethodNowTested();
    //Asserts to check correct processing took place
  }
}

And the code under test needs a constructor to enable me to inject in the Func that creates a DateTime object. The default constructor that would be called in production simply provides a Func that will return DateTime.Now when called:

public class StubbingDateTimeNow
{
  private readonly Func<DateTime> getCurrentDateTime;

  public StubbingDateTimeNow(Func<DateTime> getCurrentDateTime)
  {
    this.getCurrentDateTime = getCurrentDateTime;
  }

  public StubbingDateTimeNow() : this(() => DateTime.Now) {} //default constructor provides a Func to return DateTime.Now

  public void SomeMethodNowTested()
  {
     var dateTimeNow = getCurrentDateTime();
     if (dateTimeNow.Month == 4 && dateTimeNow.Day == 6)
     {
       //do something for the new tax year.
     }
     else
     {
       //do something for the current tax year.
     }
  }
}
Advertisements

Sorry, the comment form is closed at this time.

 
%d bloggers like this: