Ich habe eine Moose-Klasse, die Anfragen vom Typ Foo::Request
senden muss. Ich muss diese Abhängigkeit von außen zugänglich machen, damit ich die Anfrage-Implementierung in Tests leicht austauschen kann. Ich habe das folgende Attribut gefunden:
Und dann im Code:
%Vor%Und in Tests:
%Vor%Gibt es eine einfachere / mehr idiomatische Lösung?
Wie wäre es, wenn Sie in Ihren Tests eine Rolle dynamisch mit Moose :: Util :: apply_all_roles anwenden würden? Ich wollte das schon eine Weile nutzen, hatte aber noch keine Entschuldigung. Hier ist, wie ich denke, es würde funktionieren.
Ändern Sie zunächst das ursprüngliche Attribut geringfügig:
%Vor%Erstellen Sie dann eine Test :: RequestBuilder-Rolle:
%Vor%In der Zwischenzeit schreiben Sie in 't / my_client_thing.t' so etwas:
%Vor%Siehe Elch :: Manuell :: Rollen für weitere Informationen.
Mein Vorschlag, der dem Modell in chromatic's Artikel (Kommentar oben von Mike) folgt, ist dies:
In Ihrer Klasse:
%Vor%In Ihrem Test:
%Vor%Genau das, was Ihr Code tut, mit den folgenden Verbesserungen:
request
-Attribut ist ein gebrauchsfertiges Objekt; keine Notwendigkeit, den Subref zu dereferenzieren Betrachten Sie diesen Ansatz:
Definieren Sie in Ihrer Moose-Klasse eine 'abstrakte' Methode namens make_request
. Definieren Sie dann zwei Rollen, die make_request
implementieren - eine, die Foo::Request->new
aufruft und eine weitere, die Test::MockObject->new
aufruft.
Beispiel:
Ihre Hauptklasse und die zwei Rollen:
%Vor%Wenn Sie Ihre Hauptklasse testen möchten, mischen Sie sie mit der Rolle 'MakeRequestWithMock':
%Vor%Wenn Sie es mit der Foo-Implementierung von 'make_request' verwenden möchten, mischen Sie es mit der Rolle 'MakeRequestWithFoo'.
Einige Vorteile:
Sie laden nur die Module, die Sie benötigen. Zum Beispiel lädt die Klasse TestVersionOfMainMooseClass
nicht das Modul Foo::Request
.
Sie können Daten hinzufügen, die für Ihre Implementierung von make_request
als Instanzmitglieder Ihrer neuen Klasse relevant / erforderlich sind. Zum Beispiel kann Ihr ursprünglicher Ansatz, einen CODEREF zu verwenden, mit dieser Rolle implementiert werden:
Um diese Klasse zu verwenden, müssen Sie einen Initializer für request_builder
angeben, z. B.:
Als letzte Überlegung können die von Ihnen geschriebenen Rollen mit anderen Klassen verwendet werden.
Ich weiß, dass dieser Beitrag etwas alt ist, aber für jeden, der sich jetzt auf diese Frage bezieht, könnte der Anfragende ein Framework wie Brot verwenden: : Board .
Tags und Links perl dependency-injection moose