Comparing date times in a unit test can be a challenging thing. Because the date time is most of the time an external dependency you don’t fully control, it can be desirable to allow some tolerance. Unfortunately, both the Microsoft Visual Studio Tools and the NUnit Framwork don’t support such a thing out of the box. Another issue can be that the fail messages use the ToString method of objects, and the default implementation of a date time does not reveal the milliseconds, which can be quiet annoying.
This implementation gives you both the option to specify a tolerance, as it shows the milliseconds of the expected and actual date time. It even shows the difference between the two if the tolerance is bigger than zero.
[code=c#]using NUnit.Framework;
using System;
using System.Diagnostics;
using System.Text;
namespace Qowaiv.UnitTests.TestTools
{
public static class DateTimeAssert
{
///
/// considered equal if both are null, or have the same value.
/// If they are not equal an NUnit.Framework.AssertionException is
/// thrown.
///
///
/// The date time that is expected
///
///
/// The actual date time
///
///
/// The accepted tolerance between the actual and expected date time.
///
///
/// The message to display in case of failure.
///
///
/// Array of objects to be used in formatting the message
///
///
/// If the specified tolerance is negative.
///
///
/// If the assertion fails.
///
[DebuggerStepThrough]
public static void AreEqual(DateTime? expected, DateTime? actual, string message, params object[] args)
{
AreEqual(expected, actual, TimeSpan.Zero, message, args);
}
///
/// considered equal if both are null, or the difference between the
/// date times is smaller then the specified tolerance.
/// If they are not equal an NUnit.Framework.AssertionException is
/// thrown.
///
///
/// The date time that is expected
///
///
/// The actual date time
///
///
/// The accepted tolerance between the actual and expected date time.
///
///
/// The message to display in case of failure.
///
///
/// Array of objects to be used in formatting the message
///
///
/// If the specified tolerance is negative.
///
///
/// If the assertion fails.
///
[DebuggerStepThrough]
public static void AreEqual(DateTime? expected, DateTime? actual, TimeSpan tolerance, string message, params object[] args)
{
Guard.NotNegative(tolerance, “tolerance”);
if (actual.HasValue && expected.HasValue)
{
var difference = (actual.Value – expected.Value).Duration();
if (difference > tolerance)
{
var sb = new StringBuilder();
sb.AppendFormat(“Expected:<{0:yyyy-MM-dd HH:mm:ss.FFFFFFF}>. “, actual);
sb.AppendFormat(“Actual:<{0:yyyy-MM-dd HH:mm:ss.FFFFFFF}>.”, expected);
if (tolerance > TimeSpan.Zero)
{
sb.AppendFormat(” Difference:<{0:#,##0.0######} seconds>.”, difference.TotalSeconds);
}
if (!String.IsNullOrEmpty(message))
{
sb.Append(‘ ‘).AppendFormat(message, args);
}
Assert.Fail(sb.ToString());
}
}
else
{
Assert.AreEqual(expected, actual, message, args);
}
}
}
}[/code]