4 Stimmen

Test Data Builder-Muster: nützlicher oder aufwändiger?

Lassen Sie mich zunächst sagen, dass ich ein großer Fan der Eleganz dieses Musters bin - ich habe eine Gruppe von grundlegenden Entitäten, für die ich Builder implementiert habe (speziell für Tests). Allerdings habe ich festgestellt (und das ist vielleicht der Nachteil), dass ich im Laufe der Entwicklung meines Programms immer wieder zurückgehen und die Builder überarbeiten musste. Am Ende hat es sich nicht mehr gelohnt, sie auf dem neuesten Stand zu halten, und ich bin wieder dazu übergegangen, hauptsächlich eine Objekt-Mutter zu verwenden, die viele vorkonfigurierte Entitäten enthält. Sollte ich die Builder für die Zukunft weiter aktualisieren, oder sollten die TDBs erst erstellt werden, wenn das Design eine gewisse Stabilität erreicht hat und das Object Mother zu groß wird?

Außerdem habe ich festgestellt, dass ich die Builder nirgendwo sonst in der Anwendung verwende, da ich gerne die neue Syntax von .Net 3.0 für die Eigenschaftsinitialisierung verwende.

8voto

craigb Punkte 16711

Ich verwende gerne fließende Builder für das zu testende Objekt, um die Art des Objekts auszudrücken, das ich erstelle. ObjectMothers neigen dazu, unhandlich zu werden, und neigen (in den mir bekannten Implementierungen) dazu, Details der Objekterstellung zu verbergen.

Vergleichen Sie:

User fred = CreateUser("fred").WithReputation(900)
                              .WithScholarBadge()
                              .WithCriticBadge()

vs:

User fred = UserObjectMother.Fred()

Die Vorstellung auszudrücken, dass der Benutzer die Marke 900 und diese beiden speziellen Abzeichen hat, wäre mit der ObjectMother nicht zu bewerkstelligen. Die Tendenz, die ich gesehen habe, ist, dass Entwickler dann diese Methode finden, die eine Fred() was dem entspricht, was sie brauchen, also fügen sie dem Objekt weitere Attribute hinzu. Der Fluent Builder hingegen ist aussagekräftig in Bezug auf das, was gebaut wird, und es ist einfach, bei Bedarf spezifische Benutzer für den Test zu erstellen.

Allerdings verwende ich diese Muster auch ausschließlich in Testcode, da der Produktionscode diese Art von Ausdruckskraft normalerweise nicht erfordert.

1voto

Enrico Campidoglio Punkte 51948

Wenn die Pflege der Testdatenersteller zu komplex wird, würde ich empfehlen, auf ein Spotting-Framework was die Erstellung von Testobjekten mit bekanntem Zustand erleichtert.

Außerdem können Sie mit Mocks dafür sorgen, dass die Testobjekte mehr als nur einfache Stubs sind, und tatsächlich an dem teilnehmen, was der Test behauptet, indem Sie Erwartungen darüber, wie ihre Eigenschaften und Methoden aufgerufen werden.

1voto

Andrew Chaa Punkte 5562

Die Lambda-Syntax kann die fließende Schnittstelle prägnanter machen

Zum Beispiel,

User fred = new UserTestDataBuilder()
                .With(u => u.Name = "fred")
                .With(u => u.Reputation = 900)
                .With(u => u.ScholarBadge = true)
                .With(u => u.CriticBadge = true)

Sie benötigen lediglich eine Action-Methode und eine Klasse für die zu befüllenden Eigenschaften.

public class UserSpec
{
    public string Name {get; set;}
    public int Reputation {get; set;}
    ...
}

public class UserTestDataBuilder() 
{
    private UserSpec _userSpec = new UserSpec();
    public UserTestDataBuilder With(Action<UserSpec> action) 
    {
        action(_userSpec);
        return this;
    }

    public User Build() 
    {
        return new User(_userSpec.Name, _userSpec.Reputation, _userSpec.ScholarBadge, _userSpec.CriticBadge);
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X