2014-03-27 47 views

回答

8

您可以使用一个装饰这个(虽然更容易的解决方案也可能存在):

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(); 
    } 
} 
+0

+1你的装饰比我的装饰:) –

3

序言

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); 
} 
+0

+1简单的你方法更多[GOOS](http://amzn.to/VI81bP) - 方向:) –

+0

嗯,我同意你的偏移建议 - 不幸的是,这是我在项目早期阶段失去的一场“战斗” :o(。我正在测试一些我几乎无法控制的代码,所以这不是真的要交给我乐。不过,我特别使用#autofixture来创建复杂类型,并在其中包含一堆DateTime字段。我可以在创建复杂类型后手动更新这些值,但我并不真正关心这些值本身 - 我只是需要它们将“UTC”验证检查“传递”到我无法绕过的链中。我会看看装饰者:o) –

相关问题