-1

I've got this test code:

[TestMethod]
public void TestGetDatesForNthDOWOfMonth()
{
    List<DateTime> firstFridaysInFirstQuarterOf2017 = new List<DateTime>();
    // These were determined by looking at a calendar
    firstFridaysInFirstQuarterOf2017.Add(new DateTime(2017, 1, 6));
    firstFridaysInFirstQuarterOf2017.Add(new DateTime(2017, 2, 3));
    firstFridaysInFirstQuarterOf2017.Add(new DateTime(2017, 3, 3));
    DayOfWeek dow = DayOfWeek.Friday;
    DateTime startDate = new DateTime(2017, 1, 1);
    DateTime endDate = new DateTime(2017, 3, 31);
    List<DateTime> testFirstFridaysInFirstQuarterOf2017 = RoboReporterConstsAndUtils.GetDatesForNthDOWOfMonth(startDate, endDate, dow, 1);
    //Assert.AreEqual(firstFridaysInFirstQuarterOf2017, testFirstFridaysInFirstQuarterOf2017);
    Assert.AreSame(firstFridaysInFirstQuarterOf2017, testFirstFridaysInFirstQuarterOf2017);
}

The method under test is:

internal static List<DateTime> GetDatesForNthDOWOfMonth(
    DateTime startDate,
    DateTime endDate,
    DayOfWeek dayOfWeek,
    int ordinal)
{
    var foundDates = new List<DateTime>();
    // Make sure ordinal parameter is within the allowable range
    //If it's too high, set it to 5 (last week) so it returns the last
    // qualifying day of each month
    ordinal = Math.Min(Math.Max(ordinal, 1), 5);
    while (startDate < endDate)
    {
        int month = startDate.Month;
        //Set workingDate to the first day of the month.
        var workingDate = new DateTime(startDate.Year, month, 1);
        //Set workingDate to the first occurrence of the DayOfWeek parameter
        workingDate = (int)workingDate.DayOfWeek > (int)dayOfWeek
            ? workingDate.AddDays(7 - (int)workingDate.DayOfWeek + (int)dayOfWeek)
            : workingDate.AddDays((int)dayOfWeek - (int)workingDate.DayOfWeek);

        //Advance the date by the number of days required to satisfy the ordinal parameter
        workingDate = workingDate.AddDays((ordinal - 1) * 7);
        //If the date has crossed the month boundary, step back a week.
        //So the last occurrence of the target day is returned
        workingDate = workingDate.Month != month ? workingDate.AddDays(-7) : workingDate;
        foundDates.Add(workingDate);
        startDate = startDate.AddMonths(1);
    }
    return foundDates;
}

The two lists of DateTime do contain the same exact values, down to the HHMMSS. So why does the Assertion fail? Assert.AreEqual() fails, and so does Assert.AreSame()! Yes, they're not the exact same object, but their values are the same, so why the persnickitiness?

UPDATE

I tried Jon Skeet's idea here like so:

. . .
var firstNotSecond = mockedMonthsAndTruncatedYears.Except(monthsAndTruncatedYears).ToList();
var secondNotFirst = monthsAndTruncatedYears.Except(mockedMonthsAndTruncatedYears).ToList();
Assert.IsTrue((null == firstNotSecond) && (null == secondNotFirst));

...but get, "'System.Collections.Generic.List' does not contain a definition for 'Except' and no extension method 'Except' accepting a first argument of type 'System.Collections.Generic.List' could be found (are you missing a using directive or an assembly reference?)"

Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    Because they reference to a different objects. In order to compare items in List you should compare items manually. – Valentin Feb 25 '16 at 23:16
  • 1
    In addition to @Valentin's comment. Be sure the the value for ticks is the same for each DateTime variable. DateTime can have the same values down to the seconds and still contain different tick values. – MGM_Squared Feb 25 '16 at 23:20
  • Possible duplicate of [Compare two List objects for equality, ignoring order](http://stackoverflow.com/questions/3669970/compare-two-listt-objects-for-equality-ignoring-order) – Heretic Monkey Feb 25 '16 at 23:24
  • 2
    your error in the UPDATE is caused by not having 'using System.Linq' – pm100 Feb 25 '16 at 23:34

2 Answers2

1

List is a reference type, so when you compare two lists you compare references, not the values.

So in order to compare lists item, you should check every item in both lists.

Look here : Compare two List<T> objects for equality, ignoring order

Or here: Quickest way to compare two List<>

Community
  • 1
  • 1
Valentin
  • 5,380
  • 2
  • 24
  • 38
0

This is what it needs to be:

        [TestMethod]
        public void TestGetDatesForNthDOWOfMonth()
        {
            List<DateTime> firstFridaysInFirstQuarterOf2017 = new List<DateTime>
    ();
            // These were determined by looking at a calendar
            firstFridaysInFirstQuarterOf2017.Add(new DateTime(2017, 1, 6));
            firstFridaysInFirstQuarterOf2017.Add(new DateTime(2017, 2, 3));
            firstFridaysInFirstQuarterOf2017.Add(new DateTime(2017, 3, 3));
            DayOfWeek dow = DayOfWeek.Friday;
            DateTime startDate = new DateTime(2017, 1, 1);
            DateTime endDate = new DateTime(2017, 3, 31);
            List<DateTime> testFirstFridaysInFirstQuarterOf2017 = 
    RoboReporterConstsAndUtils.GetDatesForNthDOWOfMonth(startDate, endDate, dow, 1);
            var firstNotSecond = 
 firstFridaysInFirstQuarterOf2017.Except(testFirstFridaysInFirstQuarterOf2017).ToList();
            var secondNotFirst = 
    testFirstFridaysInFirstQuarterOf2017.Except(firstFridaysInFirstQuarterOf2017).To
    List();
            Assert.IsTrue((firstNotSecond.Count == 0) && (secondNotFirst.Count 
    == 0));
        }

It's interesting that these items are not being viewed as the same/equal, except when except is used.

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862