单元测试NodaTime别名DateTimeZone

问题描述 投票:1回答:1

我正在为我的扩展方法进行单元测试。

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; ...

c# unit-testing nodatime
1个回答
3
投票

看过代码之后,我们可能需要对文档进行一些修改。 TzdbDateTimeZoneSource的当前行为是返回具有所请求ID的DateTimeZone,但它使用与规范ID相关联的数据。

© www.soinside.com 2019 - 2024. All rights reserved.