2014-03-27 36 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) –

相關問題