默认情况下,AutoFixture在“本地,未指定的时间”中创建DateTime结构。
我一直试图找到一种方法来配置它以使用UTC类型创建DateTime结构,但到目前为止都没有成功。
有办法做到这一点吗?
答案 0 :(得分:11)
您可以使用装饰器(尽管也可以使用更简单的解决方案):
var fixture = new Fixture();
fixture.Customizations.Add(new UtcRandomDateTimeSequenceGenerator());
var dateTime = fixture.Create<DateTime>();
// -> The value of 'dateTime' is in Coordinated Universal Time (UTC).
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();
}
}
答案 1 :(得分:4)
<强>序言强>
AutoFixture最初是作为测试驱动开发(TDD)的工具而构建的,TDD完全是关于反馈的。本着GOOS的精神,你应该倾听你的测试。如果测试难以编写,则应考虑API设计。 AutoFixture倾向于放大那种反馈,所以我的第一反应是挑战你想要这样做的动机。
DateTime是正确的类型吗?
如果DateTime值以UTC格式确实很重要,那么System.DateTime
可能不是作业的最佳数据类型。也许DateTimeOffset会是更好的选择吗?
AutoFixture将很乐意为您创建DateTimeOffset值。
您可以在生成后更改值吗?
如果你自己使用AutoFixture创建原始值,你也可以在从AutoFixture获取它们之后转换它们:
var dt = fixture.Create<DateTime>().ToUniversalTime();
如果你真的必须改变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();
}
}
你可以使用它,就像通过测试所证明的那样:
[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);
}