我正在为我的扩展方法进行单元测试。
public static DateTimeZone GetDateTimeZone(this IDateTimeZoneProvider dateTimeZoneProvider, String timezoneId)
{
DateTimeZone dateTimeZone;
if ((dateTimeZone = dateTimeZoneProvider.GetZoneOrNull(timezoneId)) != null)
return dateTimeZone;
// Continues to try and map from TimeZoneInfo if dateTimeZone == null
}
当对该方法进行单元测试时,由于返回了DateTimeZone ID的别名,因此测试失败。>
[TestMethod] public void GetDateTimeZone_DateTimeZoneProviderHasTimezoneIdAsAlias_ReturnsDateTimeZone() { var expectedTimezoneId = "America/New_York"; var timezoneId = "US/Eastern"; var dateTimeZone = _dateTimeZoneProvider.GetDateTimeZone(timezoneId); Assert.AreEqual(expectedTimezoneId, dateTimeZone.Id); }
如您所见,我期望区域ID列(https://nodatime.org/TimeZones)中有什么,但是将返回别名“ US / Eastern”。这尤其令人惊讶,因为有关GetZoneOrNull(https://nodatime.org/2.4.x/api/NodaTime.IDateTimeZoneProvider.html#NodaTime_IDateTimeZoneProvider_GetZoneOrNull_System_String_)的文档说:“请注意,如果提供的ID是别名,则此ID返回的DateTimeZone可能具有与请求的ID不同的ID。”
[阅读后,“还请注意,对于相同ID的连续请求,不需要此方法返回相同的DateTimeZone实例;但是,为给定ID返回的所有实例必须进行相等比较。”我以为,别名DateTimeZone可能等同于未别名。
[TestMethod] public void GetDateTimeZone_DateTimeZoneProviderHasTimezoneIdAsAlias_ReturnsDateTimeZone() { var expectedDateTimeZone = _dateTimeZoneProvider.GetZoneOrNull("America/New_York"); var timezoneId = "US/Eastern"; var dateTimeZone = _dateTimeZoneProvider.GetDateTimeZone(timezoneId); Assert.AreEqual(expectedDateTimeZone, dateTimeZone); }
但是,不是。调用扩展方法的代码实际上并不关心ID,因为它使用DateTimeZone将LocalTime转换为Utc。
IDateTimeZoneProvider dateTimeZoneProvider = DateTimeZoneProviders.Tzdb; var dateTimeZone = dateTimeZoneProvider.GetDateTimeZone(timezoneId); var zonedDateTime = dateTimeZone.AtLeniently(localDateTime); return zonedDateTime.ToDateTimeUtc();
因此,它将花费localDateTime时当前的偏移量。但是,出于单元测试的目的,我不能像“ America / New_York”示例中那样仅检查偏移量,因为该偏移量有时是-5,而有时是-4。断言在单元测试中它是-5或-4不会让人感到生硬。我应该如何测试别名的DateTimeZone?
这里是使用已知日期和时间的特定偏移量的更新的单元测试。
[TestMethod]
public void GetDateTimeZone_DateTimeZoneProviderHasTimezoneIdAsAlias_ReturnsDateTimeZone()
{
var expectedOffset = Offset.FromHours(-5);
var specificDateTimeWithKnownUtcOffset = new DateTime(2020, 1, 15, 8, 29, 15, DateTimeKind.Utc);
var instant = Instant.FromDateTimeUtc(specificDateTimeWithKnownUtcOffset);
var timezoneId = "US/Eastern";
var dateTimeZone = _dateTimeZoneProvider.GetDateTimeZone(timezoneId);
Assert.AreEqual(expectedOffset, dateTimeZone.GetUtcOffset(instant));
}
我正在为我的扩展方法进行单元测试。公共静态DateTimeZone GetDateTimeZone(此IDateTimeZoneProvider dateTimeZoneProvider,字符串timezoneId){DateTimeZone dateTimeZone; ...
看过代码之后,我们可能需要对文档进行一些修改。 TzdbDateTimeZoneSource
的当前行为是返回具有所请求ID的DateTimeZone
,但它使用与规范ID相关联的数据。