Проведено локальное тестирование по местному времени - PullRequest
1 голос
/ 26 июня 2019

Я разрабатываю консольное приложение dot net core 2.2 для преобразования файлов .csv в файлы .xml.

У меня есть модульный тест для проверки создания определенного имени файла XML. Часть имени файла - это время. Это время всегда должно быть местным. Использование dotnet core 2.2 с xUnit.

Тест проходит локально (Нидерланды, культура nl-NL), но не проходит при тестировании в Azure с использованием агента хостинга. Этот хостинг-агент находится где-то в США (культура en-US).

Чтобы исправить этот тест, я создал определенную область выполнения в определенной культуре. Я предположил, что .LocalTime DateTimeOffset дает мне местное время, специфичное для культуры, но оно остается в nl-NL, когда я отлаживаю его в VS2019.

Почему?

Вот некоторые части кода (убран код для лучшего чтения):

public class OutputIdentifierServiceTests
{
   [Fact(DisplayName = "Valid filename is created")]
   public void GetOutputIdentifier_ReturnsFilename()
   {
       // Arrange

       // utc time          = 16:52:33
       // local nl-NL time  = 18:52:33

       using (new CurrentCultureScope("en-US"))
       {
           var currentTimeUtc = new DateTimeOffset(2019, 6, 14, 16, 52, 33, TimeSpan.Zero);

           _systemClockServiceMock.SetupGet(s => s.UtcNow).Returns(currentTimeUtc);

           var sut = CreateSut();

           // Act
           var filename = sut.GetOutputIdentifier();

           // Assert
           Assert.Equal("20190614T165233", filename);
       }
   }
}

И класс CurrentCultureScope:

public class CurrentCultureScope : IDisposable
    {
        private readonly CultureInfo _culture;
        private readonly CultureInfo _uiCulture;

        private bool _disposed = false;

        public CurrentCultureScope(string name)
        {
            _culture = Thread.CurrentThread.CurrentCulture;
            _uiCulture = Thread.CurrentThread.CurrentUICulture;

            Thread.CurrentThread.CurrentCulture = new CultureInfo(name);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(name);
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    Thread.CurrentThread.CurrentCulture = _culture;
                    Thread.CurrentThread.CurrentUICulture = _uiCulture;
                }

                _disposed = true;
            }
        }
    }
}

И класс, создающий выходной идентификатор:

public string GetOutputIdentifier()
        {
            var currentTimeUtc = _systemClockService.UtcNow;

            var localTime = currentTimeUtc.LocalDateTime;

            var creationDate = localTime.ToString("yyyyMMdd");
            var creationTime = localTime.ToString("HHmmss");

            // code removed
        }

1 Ответ

1 голос
/ 26 июня 2019

Я исправил это в функции идентификатора вывода (спасибо Panagiotis Kanavos, см. Комментарии).CurrentCultureScope не требуется.

 var currentTimeUtc = _systemClockService.UtcNow;

 var nlZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");

 var localTime = TimeZoneInfo.ConvertTime(currentTimeUtc, nlZone);
...