为什么这些相同的结果无法通过 AreEqual 和 AreSame 测试断言?
Why do these identical results fail the AreEqual and AreSame test assertions?
我有这个测试代码:
[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);
}
被测方法为:
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;
}
DateTime 的两个列表包含完全相同的值,一直到 HHMMSS。那么为什么断言会失败呢? Assert.AreEqual() 失败,Assert.AreSame() 也是如此!是的,它们不是完全相同的对象,但它们的值是相同的,那么为什么要这么挑剔呢?
更新
我试过 Jon Skeet 的想法 here 像这样:
. . .
var firstNotSecond = mockedMonthsAndTruncatedYears.Except(monthsAndTruncatedYears).ToList();
var secondNotFirst = monthsAndTruncatedYears.Except(mockedMonthsAndTruncatedYears).ToList();
Assert.IsTrue((null == firstNotSecond) && (null == secondNotFirst));
...但是得到,“'System.Collections.Generic.List' 不包含 'Except' 的定义并且没有扩展方法 'Except' 可以找到接受类型 'System.Collections.Generic.List' 的第一个参数(您是否缺少 using 指令或程序集引用?)"
列表是引用类型,因此当您比较两个列表时,您比较的是引用,而不是值。
因此,为了比较列表项目,您应该检查两个列表中的每个项目。
看这里:Compare two List<T> objects for equality, ignoring order
或此处:Quickest way to compare two List<>
这是需要的:
[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));
}
有趣的是,这些项目没有被视为 same/equal,除非使用 except。
我有这个测试代码:
[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);
}
被测方法为:
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;
}
DateTime 的两个列表包含完全相同的值,一直到 HHMMSS。那么为什么断言会失败呢? Assert.AreEqual() 失败,Assert.AreSame() 也是如此!是的,它们不是完全相同的对象,但它们的值是相同的,那么为什么要这么挑剔呢?
更新
我试过 Jon Skeet 的想法 here 像这样:
. . .
var firstNotSecond = mockedMonthsAndTruncatedYears.Except(monthsAndTruncatedYears).ToList();
var secondNotFirst = monthsAndTruncatedYears.Except(mockedMonthsAndTruncatedYears).ToList();
Assert.IsTrue((null == firstNotSecond) && (null == secondNotFirst));
...但是得到,“'System.Collections.Generic.List' 不包含 'Except' 的定义并且没有扩展方法 'Except' 可以找到接受类型 'System.Collections.Generic.List' 的第一个参数(您是否缺少 using 指令或程序集引用?)"
列表是引用类型,因此当您比较两个列表时,您比较的是引用,而不是值。
因此,为了比较列表项目,您应该检查两个列表中的每个项目。
看这里:Compare two List<T> objects for equality, ignoring order
或此处:Quickest way to compare two List<>
这是需要的:
[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));
}
有趣的是,这些项目没有被视为 same/equal,除非使用 except。