默认情况下,AutoFixture在"本地,未指定的时间"中创建DateTime结构.
我一直试图找到一种方法来配置它来创建UTC类型的DateTime结构,但到目前为止都没有成功.
有没有办法做到这一点?
Nik*_*nis 11
您可以使用Decorator(虽然也可能存在更简单的解决方案):
var fixture = new Fixture();
fixture.Customizations.Add(new UtcRandomDateTimeSequenceGenerator());
var dateTime = fixture.Create<DateTime>();
// -> The value of 'dateTime' is in Coordinated Universal Time (UTC).
Run Code Online (Sandbox Code Playgroud)
的UtcRandomDateTimeSequenceGenerator定义为:
internal class UtcRandomDateTimeSequenceGenerator : ISpecimenBuilder
{
private readonly ISpecimenBuilder innerRandomDateTimeSequenceGenerator;
internal UtcRandomDateTimeSequenceGenerator()
{
this.innerRandomDateTimeSequenceGenerator =
new RandomDateTimeSequenceGenerator();
}
public object Create(object request, ISpecimenContext context)
{
var result =
this.innerRandomDateTimeSequenceGenerator.Create(request, context);
if (result is NoSpecimen)
return result;
return ((DateTime)result).ToUniversalTime();
}
}
Run Code Online (Sandbox Code Playgroud)
前言
AutoFixture最初是作为测试驱动开发(TDD)的工具而构建的,而TDD只是关于反馈的。本着GOOS的精神,您应该听听测试。如果测试很难编写,则应考虑API设计。AutoFixture倾向于放大这种反馈,所以我的第一反应是挑战您想要这样做的动力。
DateTime是正确的类型吗?
如果将DateTime值设置为UTC确实很重要,则可能System.DateTime不是最佳的数据类型。也许DateTimeOffset将是一个更好的选择?
AutoFixture会很高兴为您创建DateTimeOffset值。
值生成后可以更改吗?
如果您使用的是AutoFixture本身创建原始值,则也可以在从AutoFixture获取它们之后将它们转换:
var dt = fixture.Create<DateTime>().ToUniversalTime();
Run Code Online (Sandbox Code Playgroud)
如果您真的必须更改AutoFixture的行为
但是,如果您不控制要测试的API,并且这些DateTime值深深嵌套在某些数据结构中,则需要配置AutoFixture以在UTC中构建DateTime值。
这是一种实现方法:
public class UtcConverter : ISpecimenBuilder
{
private readonly ISpecimenBuilder builder;
public UtcConverter(ISpecimenBuilder builder)
{
this.builder = builder;
}
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (t == null && t != typeof(DateTime))
return new NoSpecimen(request);
var specimen = this.builder.Create(request, context);
if (!(specimen is DateTime))
return new NoSpecimen(request);
return ((DateTime)specimen).ToUniversalTime();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以像通过测试所示那样使用它:
[Fact]
public void ResolveUtcDate()
{
var fixture = new Fixture();
fixture.Customizations.Add(
new UtcConverter(
new RandomDateTimeSequenceGenerator()));
var dt = fixture.Create<DateTime>();
Assert.Equal(DateTimeKind.Utc, dt.Kind);
}
Run Code Online (Sandbox Code Playgroud)