Dependency-Injektion für Moose-Klassen

9

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:

%Vor%

Und dann im Code:

%Vor%

Und in Tests:

%Vor%

Gibt es eine einfachere / mehr idiomatische Lösung?

    
zoul 19.08.2011, 07:38
quelle

4 Antworten

2

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.

    
Eric Johnson 20.08.2011 07:09
quelle
2

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:

  1. Machen Sie das Attribut schreibgeschützt und setzen Sie es, wenn möglich, im Konstruktor ein, um eine bessere Kapselung zu erreichen.
  2. Ihr request -Attribut ist ein gebrauchsfertiges Objekt; keine Notwendigkeit, den Subref zu dereferenzieren
dmaestro12 21.08.2011 13:52
quelle
1

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:

%Vor%

Um diese Klasse zu verwenden, müssen Sie einen Initializer für request_builder angeben, z. B.:

%Vor%

Als letzte Überlegung können die von Ihnen geschriebenen Rollen mit anderen Klassen verwendet werden.

    
ErikR 20.08.2011 05:51
quelle
0

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 .

    
wds 05.05.2015 15:15
quelle