2014-03-27 4 views
5

Standardmäßig erstellt AutoFixture DateTime-Strukturen in "lokaler, nicht angegebener Zeit".Lassen Sie AutoFixture DateTime in UTC erstellen?

Ich habe versucht, eine Möglichkeit zu finden, es zu konfigurieren, um DateTime-Strukturen mit UTC-Art zu erstellen, aber bisher nicht erfolgreich.

Gibt es eine Möglichkeit, dies zu tun?

Antwort

8

Sie können für diese Dekorateur verwenden (obwohl einfachere Lösungen auch existieren könnten):

var fixture = new Fixture(); 
fixture.Customizations.Add(new UtcRandomDateTimeSequenceGenerator()); 

var dateTime = fixture.Create<DateTime>(); 
// -> The value of 'dateTime' is in Coordinated Universal Time (UTC). 

Die UtcRandomDateTimeSequenceGenerator ist definiert als:

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 Ihr Decorator ist einfacher als mein Ausstatter :) –

3

Präambel

AutoFixture ursprünglich Build als ein Werkzeug für Test-Driven Development (TDD), und TDD ist alles über Rückmeldung. Im Geiste der GOOS, sollten Sie hören Sie Ihre Tests. Wenn die Tests schwer zu schreiben sind, sollten Sie Ihr API-Design in Betracht ziehen. AutoFixture neigt dazu, diese Art von Feedback zu verstärken, so ist meine erste Reaktion, um Ihre Motivation herausfordern, dies zu tun.

Ist DateTime der richtige Typ?

Wenn es wirklich darauf ankommt, dass DateTime-Werte in UTC sind, dann ist vielleicht System.DateTime nicht der beste Datentyp für den Job. Vielleicht wäre DateTimeOffset eine bessere Option?

AutoFixture erstellt gerne DateTimeOffset-Werte für Sie.

Können Sie den Wert ändern, nachdem er generiert wurde?

Wenn Sie AutoFixture verwenden selbst die primitiven Werte zu erstellen, können Sie auch wandeln sie nur, nachdem Sie sie aus AutoFixture erhalten:

var dt = fixture.Create<DateTime>().ToUniversalTime(); 

Wenn Sie wirklich müssen AutoFixture Verhalten ändern

Wenn Sie jedoch die zu testende API nicht kontrollieren und diese DateTime-Werte in einer Datenstruktur tief verschachtelt sind, müssen Sie AutoFixture so konfigurieren, dass DateTime-Werte in UTC erstellt werden.

Hier ist eine Möglichkeit, es zu tun:

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

Sie können es verwenden, von dieser vergänglichen Test demonstriert wie:

[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 Ihre Ansatz ist mehr [GOOS] (http://amzn.to/VI81bP) -orientiert :) –

+0

Nun, ich stimme Ihnen mit dem Offset-Vorschlag zu - leider war das ein "Kampf", den ich in den frühen Phasen des Projekts verloren habe : o (. Ich teste gerade einen Code, über den ich sehr wenig Kontrolle habe, also liegt es nicht an mir, ihn zu übergeben le. Allerdings verwende ich #autofixture, um komplexe Typen mit einer Reihe von DateTime-Feldern in ihnen zu erstellen.Ich kann die Werte manuell aktualisieren, nachdem der komplexe Typ erstellt wurde, aber ich interessiere mich nicht wirklich für die Werte selbst - ich brauche sie nur, um eine UTC-Validierungsprüfung weiter unten in der Kette durchzuführen, die ich nicht umgehen kann. Ich werde in den Dekorateur schauen: o) –