Я работаю над модульным тестом для моего метода расширения.
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.
[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);
}
Как видите, я ожидаю, что находится в столбце Zone Id (https://nodatime.org/TimeZones), но вместо этого возвращается псевдоним "US / Eastern". Это особенно удивительно, поскольку в документации по GetZoneOrNull (https://nodatime.org/2.4.x/api/NodaTime.IDateTimeZoneProvider.html#NodaTime_IDateTimeZoneProvider_GetZoneOrNull_System_String_) говорится: «Обратите внимание, что при этом может возвращаться DateTimeZone, у которого идентификатор отличается от запрошенного, если указанный идентификатор является псевдонимом».
После прочтения «Обратите также внимание, что этот метод не обязан возвращать один и тот же экземпляр DateTimeZone для последовательных запросов одного и того же идентификатора; однако все экземпляры, возвращаемые для данного идентификатора, должны сравниваться как равные». Я подумал, что, возможно, aliased DateTimeZone будет приравнен к unaliased.
[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);
}
Но это не так. Код, который вызывает метод расширения, на самом деле не заботится об идентификаторе, так как он использует DateTimeZone для преобразования из LocalTime в Ut c.
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, не кажется кошерным. Как мне go проверять псевдоним DateTimeZone?
UPDATE
Вот обновленный модульный тест с указанием c даты и времени, когда смещение известно.
[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));
}