当地时间特定单元测试失败
Local time specific unit test fails
我正在开发 dot net core 2.2 控制台应用程序以将 .csv 文件转换为 .xml 文件。
我有一个单元测试来测试特定 xml 文件名的创建。文件名的一部分是时间。此时间部分应始终为本地时间。
将 dotnet 核心 2.2 与 xUnit 结合使用。
本地测试成功(荷兰,文化 nl-NL),但在 Azure 中使用托管代理测试时失败。此托管代理托管在美国某处(文化 en-US)。
为了修复这个测试,我在特定的文化中创建了一个特定的 运行 范围。
我假设 DateTimeOffset 的 .LocalTime 为我提供了特定于文化的本地时间,但是当我在 VS2019 中调试它时它停留在 nl-NL。
为什么?
以下是一些代码部分(删除了一些代码以便更好地阅读):
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 class:
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;
}
}
}
}
并且 class 创建输出标识符:
public string GetOutputIdentifier()
{
var currentTimeUtc = _systemClockService.UtcNow;
var localTime = currentTimeUtc.LocalDateTime;
var creationDate = localTime.ToString("yyyyMMdd");
var creationTime = localTime.ToString("HHmmss");
// code removed
}
我在输出标识符函数中修复了它(感谢 Panagiotis Kanavos,见评论)。不需要 CurrentCultureScope。
var currentTimeUtc = _systemClockService.UtcNow;
var nlZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
var localTime = TimeZoneInfo.ConvertTime(currentTimeUtc, nlZone);
我正在开发 dot net core 2.2 控制台应用程序以将 .csv 文件转换为 .xml 文件。
我有一个单元测试来测试特定 xml 文件名的创建。文件名的一部分是时间。此时间部分应始终为本地时间。 将 dotnet 核心 2.2 与 xUnit 结合使用。
本地测试成功(荷兰,文化 nl-NL),但在 Azure 中使用托管代理测试时失败。此托管代理托管在美国某处(文化 en-US)。
为了修复这个测试,我在特定的文化中创建了一个特定的 运行 范围。 我假设 DateTimeOffset 的 .LocalTime 为我提供了特定于文化的本地时间,但是当我在 VS2019 中调试它时它停留在 nl-NL。
为什么?
以下是一些代码部分(删除了一些代码以便更好地阅读):
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 class:
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;
}
}
}
}
并且 class 创建输出标识符:
public string GetOutputIdentifier()
{
var currentTimeUtc = _systemClockService.UtcNow;
var localTime = currentTimeUtc.LocalDateTime;
var creationDate = localTime.ToString("yyyyMMdd");
var creationTime = localTime.ToString("HHmmss");
// code removed
}
我在输出标识符函数中修复了它(感谢 Panagiotis Kanavos,见评论)。不需要 CurrentCultureScope。
var currentTimeUtc = _systemClockService.UtcNow;
var nlZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
var localTime = TimeZoneInfo.ConvertTime(currentTimeUtc, nlZone);