2016-06-27 9 views
1

Ich versuche, eine Klasse zu testen, die andere Klassen hat (dependency injection), die als Klasseneigenschaften gespeichert sind. (Eine Einstellungsklasse, zum Beispiel das Ergebnis einer Factory).In welcher Reihenfolge werden phpunit-Tests ausgeführt?

Also, in Pseudo-Code, ist es das, was ich mit zu tun habe:

//Get settings for this user. 
$settings = SettingsFactory::GetSettings(); 

//Create widget that uses settings 
$widget = new Widget($settings); 

Nun, natürlich, wenn wir Code Refactoring und brechen SettingsFactory :: GetSettings(), wird der Konstruktor für Widget scheitern. Aber nicht unbedingt, weil mit Widget irgendetwas nicht stimmt.

Also, ich möchte diese Komponenten in der Reihenfolge testen, überspringen "später" Tests, wenn "frühe" Tests fehlschlagen.

meine derzeitige Struktur für Tests vor:

tests\vendor\Settings\SettingsTest.php 
tests\vendor\Widget\WidgetTest.php 

PHPUnit SettingsTest.php testen, muss (und haben alles passieren), bevor WidgetTest.php ausgeführt wird sinnvoll sein.

Ich denke, ich muss @depends verwenden, aber das scheint auf einen einzelnen Klassenbereich beschränkt zu sein.

This question scheint ein Teil des Puzzles zu halten, aber ich bin mir nicht sicher, wie zu implementieren.

Wie schreibe ich (Struktur) diese Tests?

Antwort

1

Einer der großen Vorteile von DI ist, dass Sie Probleme wie diese vermeiden können, indem Sie ein Pseudo-$settings-Objekt injizieren, das sich so verhält, wie Sie es möchten. Dies gibt Ihnen einen echten Unit-Test von Widget, ohne uns um die Details der Implementierung von Einstellungen:

$mockSettings = $this->createMock(Settings::class); 
$mockSettings->method('someMethod')->willReturn('something'); 
$widget = new Widget($mockSettings); 

// assertions here 
+0

Das ist wahr, aber hier ist mein Problem (das ist eher, wie ich über das Problem denke als ein Problem mit dem Code oder PHPUnit) ... Wenn ich drei Klassen habe, die von den Einstellungen abhängen, muss ich Einstellungen für jede dieser Klassen/Tests nachahmen. Jetzt, wenn ich die Einstellungen aktualisiere, um ihre Funktionalität zu ändern, muss ich zurückgehen und ALLE diese Tests ändern. Ich sollte es an einem Ort ändern können und es in vielen Tests nützlich sein. – DrDamnit

+0

Komponententests sollten unabhängig sein, also versuchen Sie etwas zu erzwingen, das hier eine schlechte Übung ist. Das Ändern der Schnittstelle einer weit verbreiteten Klasse * sollte sich signifikant auf das Testen der abhängigen Klassen auswirken, da sie von dieser Schnittstelle abhängen. Wenn es weitgehend wiederverwendet wird, können Sie einen wiederverwendbaren Mock/Stub erstellen, oder Sie können die Einstellungsfactory in einen try/catch umbrechen und den übersprungenen Test markieren. – cmbuckley

+0

OK, ich höre dich. Das bedeutet, dass es üblich ist, Code von einem Test auf einen anderen zu kopieren. Dachte das könnte Code riechen ...? Denn wenn ich das in meiner tatsächlichen Codebasis hätte, würde es refaktorisiert werden. Dies ist bei Komponententests nicht der Fall? – DrDamnit