How to Assert DateTime in NUnit
NUnit has added built-in support for this using the keyword Within.
DateTime now = DateTime.Now;
DateTime later = now + TimeSpan.FromHours(1.0);
Assert.That(later.Is.EqualTo(now).Within(TimeSpan.FromHours(3.0));
Assert.That(later, Is.EqualTo(now).Within(3).Hours;
So you don’t need to write a logic to test DateTimes.
How to Assert DateTime in MSTest
You will need an enum and a static class. The enum will hold the delta DateTime types- Seconds, Minutes, etc.
public enum DateTimeDeltaType
{
Days,
Minutes
}
Next use the below class to assert DateTimes with particular delta count.
public static class DateTimeAssert
{
public static void AreEqual(DateTime? expectedDate, DateTime? actualDate, DateTimeDeltaType deltaType, int count)
{
if (expectedDate == null && actualDate == null)
{
return;
}
else if (expectedDate == null)
{
throw new NullReferenceException("The expected date was null");
}
else if (actualDate == null)
{
throw new NullReferenceException("The actual date was null");
}
TimeSpan expectedDelta = GetTimeSpanDeltaByType(deltaType, count);
double totalSecondsDifference = Math.Abs(((DateTime)actualDate – (DateTime)expectedDate).TotalSeconds);
if (totalSecondsDifference > expectedDelta.TotalSeconds)
{
throw new Exception(string.Format("Expected Date: {0}, Actual Date: {1} \nExpected Delta: {2}, Actual Delta in seconds- {3} (Delta Type: {4})",
expectedDate,
actualDate,
expectedDelta,
totalSecondsDifference,
deltaType));
}
}
private static TimeSpan GetTimeSpanDeltaByType(DateTimeDeltaType type, int count)
{
TimeSpan result = default(TimeSpan);
switch (type)
{
case DateTimeDeltaType.Days:
result = new TimeSpan(count, 0, 0, 0);
break;
case DateTimeDeltaType.Minutes:
result = new TimeSpan(0, count, 0);
break;
default: throw new NotImplementedException("The delta type is not implemented.");
}
return result;
}
}
DateTimeAssert.AreEqual(
new DateTime(2014, 10, 10, 20, 22, 16),
new DateTime(2014, 10, 11, 20, 22, 16),
DateTimeDeltaType.Days,
1);
Improved Version
Almost half year after initial publication, I created an even better implementation of the class. Credits go to my great readers in CodeProject. Thank you!
public static class DateTimeAssert
{
public static void AreEqual(DateTime? expectedDate, DateTime? actualDate, TimeSpan maximumDelta)
{
if (expectedDate == null && actualDate == null)
{
return;
}
else if (expectedDate == null)
{
throw new NullReferenceException("The expected date was null");
}
else if (actualDate == null)
{
throw new NullReferenceException("The actual date was null");
}
double totalSecondsDifference = Math.Abs(((DateTime)actualDate – (DateTime)expectedDate).TotalSeconds);
if (totalSecondsDifference > maximumDelta.TotalSeconds)
{
throw new Exception(string.Format("Expected Date: {0}, Actual Date: {1} \nExpected Delta: {2}, Actual Delta in seconds- {3}",
expectedDate,
actualDate,
maximumDelta,
totalSecondsDifference));
}
}
}
This version usage is more expressive and gives the freedom to use any Delta:
DateTimeAssert.AreEqual(
new DateTime(2014, 10, 10, 20, 22, 16),
new DateTime(2014, 10, 11, 20, 22, 16),
TimeSpan.FromMilliSeconds(500);
DateTimeAssert.AreEqual(
new DateTime(2014, 10, 10, 20, 22, 16),
new DateTime(2014, 10, 11, 20, 22, 16),
TimeSpan.FromMinutes(0.5); // half a minute = 30s 