روش صحیح تست DateTime در NUnit و MSTest
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه

وقتی ما تست‌های Unit - Integration - UI را می‌نویسیم، به طور معمول پیش می‌آید که بخواهیم آبجکتی را نیز از نوع DateTime، اثبات کنیم (Assert.That). وقتی دو DateTime را با هم مقایسه می‌کنیم، معمولا این دو به خاطر ثانیه و یا میلی ثانیه با هم برابر نمی‌شوند. به همین دلیل ما به راه بهتری برای مقایسه نیاز داریم. برای مثال اگر بخواهیم دو تاریخ زیر را مقایسه کنیم:
2016-11-13 21:03:20  <=>  2016-11-13 21:03:21  
این دو تاریخ تقریبا با هم برابرند و تنها 1 ثانیه با هم اختلاف دارند. در بیشتر موارد 1 ثانیه مسئله مهمی نیست و قابل چشم پوشی می‌باشد. بنابراین ما نیاز به متدی برای اثبات داریم که بتوانیم آن را برای چشم پوشی از 1 ثانیه اختلاف، تنظیم کنیم.

چگونگی اثبات کردن DateTime در NUnit

NUnit  با استفاده از کلمه کلیدی Within این کار را به صورت کامل پشتیبانی کرده است.
DateTime now = DateTime.Now;
DateTime later = now + TimeSpan.FromHours(1.0);

Assert.That( now, Is.EqualTo(now) );
Assert.That( later, Is.EqualTo(now).Within( TimeSpan.FromHours(3.0) ) );
Assert.That( later, Is.EqualTo(now).Within(3).Hours );
بنابراین نیازی به پیاده سازی متد سفارشی نیست.

چگونگی اثبات کردن DateTime در MSTest

با استفاده از متد AreEqual در کلاس زیر می‌توان دو تاریخ را با هم مقایسه کرد و میزان اختلاف قابل چشم پوشی را نیز با استفاده از پارامتر maximum تعیین کرد.
public static class DateTimeAssert
{
    public static void AreEqual( DateTime? expectedDate,
                                 DateTime? actualDate,
                                 TimeSpan maximum )
    {
        if ( expectedDate == null && actualDate == null )
            return;

        if ( expectedDate == null )
            throw new NullReferenceException( "The expected date was null" );

        if ( actualDate == null )
            throw new NullReferenceException( "The actual date was null" );

        var totalSecondsDifference = Math.Abs( ( actualDate.Value - expectedDate.Value ).TotalSeconds );
        if ( totalSecondsDifference > maximum.TotalSeconds )
        {
            throw new Exception( $"Expected Date: {expectedDate}, Actual Date: {actualDate} Expected: {maximum}, Total Seconds Difference: {totalSecondsDifference}" );
        }
    }
}
برای استفاده:
DateTimeAssert.AreEqual( new DateTime(2016, 11, 12, 21, 4, 5),
                         new DateTime(2016, 11, 13, 21, 4, 5),
                         TimeSpan.FromMilliSeconds(500));
DateTimeAssert.AreEqual( new DateTime(2016, 11, 12, 21, 4, 5),
                         new DateTime(2016, 11, 13, 21, 4, 5),
                         TimeSpan.FromMinutes(0.5)); // half a minute = 30s