Rolf B: PHP-Klassen in Framework global verfügbar machen

Beitrag lesen

Hallo Matti,

die reine Lehre ist mir schon klar, aber ich kämpfe oft genug damit, sie auch durchzuhalten.

Es kommt ja durchaus vor, dass irgendwelche Komponenten weitere Subkomponenten erzeugen müssen, und wenn ich alles von "ganz oben" hinein injizieren will, habe ich am Ende eine unüberschaubare Parameterleiste.

In einer einfache Funktionsklasse, die wenig Abhängigkeiten hat, lässt sich das leichter erledigen. Aber in einer Web-Anwendung habe ich typischerweise den Zugriff auf die Session, auf die Request-Daten und auf die Datenbank. In einer Controller-Klasse, die ich testen können möchte, will ich aber nicht $_GET, $_POST oder $_SESSION stehen haben. Natürlich, für Tests kann ich die Fake-bestücken, aber das ist PHP typisch. In C#, wo ich öfter unterwegs bin, gibt's dafür Objekte und die kann ich nicht mal eben so wegmocken. Also muss ich sie kapseln, und entweder injiziere ich jede einzelne Kapsel oder ich erstelle ein Kontextobjekt, wo alles beieinander ist. Damit habe ich einen globalen Scope, ja, aber er ist für Tests isolierbar und austauschbar.

In einer Web-Anwendung habe ich auch oft genug nur eine index.php, die nichts weiter tut als das Objektframework für die Requestverarbeitung zu errichten, und den Request dann dem Router zu übergeben. Der ermittelt einen Controller und delegiert den Job dorthin. Der Controller braucht dann Zugriff auf die DB-Repositories und muss passende Views erzeugen - die kann und will ich nicht aus dem Router injizieren. Ich brauche also eine View-Factory, DIE kann ich injizieren und für Tests einen Ersatz [1] unterschieben. Letztlich sind das alles Dinge, die in den Runtime-Kontext passen. Controller in Web-Anwendungen haben ein nichttriviales Umfeld, also ist auch der Test nichttrivial. Oder ich bin zu blöd dafür. Würde ich nie ausschließen…

Rolf

--
sumpsi - posui - obstruxi

  1. Mein Lieblingstool für Unittests in C# heißt NSubstitute, und zwar wegen dieses Handbuchsatzes: We could ask for a stub, mock, fake, spy, test double etc., but why bother when we just want to substitute an instance we have some control over? ↩︎