Durchführen von Komponententests mit verschachtelten Abhängigkeiten und Factory-Klassen

Ich bin neu in Unit Testing und PHPUnit, lese aber in letzter Zeit viel über Entwurfsmuster und isolierte Tests und habe mich dazu entschlossen, eine Anwendung, an der ich arbeite, umzustrukturieren, um statische Klassen, Singletons, fest codierte Abhängigkeiten und Fehler zu beseitigen Alles andere, was im globalen Rahmen definiert ist, um es hoffentlich "testbar" zu machen, und kein Ärgernis für die Zukunft, da es sich um ein langfristiges Projekt handelt.

Bisher glaube ich, die Theorie hinter Unit-Tests zu verstehen, aber ich habe mich gefragt, in einem Szenario, in dem man die Verarbeitung verschachtelter Abhängigkeiten von Objekten an eine Factory delegiert, wie man beim Testen der Factory vorgehen soll oder ob es nur überflüssig ist, sie zu testen ? Und was ist der beste Ansatz, um zu testen, ob die "Kette" von Abhängigkeiten synchron funktioniert?

Lassen Sie mich die Fragen veranschaulichen. Angenommen, Sie haben den folgenden "Legacy" -Code:

<code>class House {
    protected $material;
    protected $door;
    protected $knob;

    public function __construct() {
        $this->door = new Door();
        $this->knob = $this->door->getKnob();
        $this->material = "stone";

        echo "House material: ".$this->material . PHP_EOL . "<br/>";
        echo "Door material: ".$this->door->getMaterial() . PHP_EOL . "<br/>";
        echo "Knob material: ".$this->knob->getMaterial() . PHP_EOL . "<br/>";
    }
}

class Door {
    protected $material;
    protected $knob;

    public function __construct() {
        $this->knob = new Knob();
        $this->material = "wood";
    }

    public function getKnob() {
        return $this->knob;
    }

    public function getMaterial () {
        return $this->material;
    }

}

class Knob {
    protected $material;

    public function __construct() {
        $this->material = "metal";
    }

    public function getMaterial () {
        return $this->material;
    }
}

$house = new House();
</code>

Dies ist (soweit ich weiß) schlecht für Unit-Tests, daher ersetzen wir die fest codierten Abhängigkeiten durch DI + eine Factory-Klasse:

<code>class House {
    protected $material;
    protected $door;
    protected $knob;

    public function __construct($door) {
        $this->door = $door;
        $this->knob = $this->door->getKnob();
        $this->material = "stone";

        echo "House material: ".$this->material . PHP_EOL . "<br/>";
        echo "Door material: ".$this->door->getMaterial() . PHP_EOL . "<br/>";
        echo "Knob material: ".$this->knob->getMaterial() . PHP_EOL . "<br/>";
    }
}

class Door {
    protected $material;
    protected $knob;

    public function __construct($knob) {
        $this->knob = $knob;
        $this->material = "wood";
    }

    public function getKnob() {
        return $this->knob;
    }

    public function getMaterial () {
        return $this->material;
    }

}

class Knob {
    protected $material;

    public function __construct() {
        $this->material = "metal";
    }

    public function getMaterial () {
        return $this->material;
    }
}

class HouseFactory {
    public function create() {
        $knob = new Knob();
        $door = new Door($knob);
        $house = new House($door);

        return $house;
    }
}

$houseFactory = new HouseFactory();
$house = $houseFactory->create();
</code>

Ab und zu können (soweit ich weiß) House, Door und Knob Unit-Tests mit verspotteten Abhängigkeiten durchgeführt werden. Aber:

1) Was passiert jetzt mit HouseFactory?

Sollte man nur:

Nicht testen, da es noch keine prüfenswerte Anwendungslogik gibt und Factories im Allgemeinen so bleiben. Angenommen, wenn die unabhängigen Tests für House, Door & Knob bestanden wurden, sollte die Fabrik in Ordnung sein.Refaktorieren Sie die Factory irgendwie, dh verwenden Sie Funktionen innerhalb der Klasse, um jede Instanz so abzurufen, dass Sie diese Funktionen über PHPUnit überschreiben können, um Scheinobjekte zurückzugeben, nur für den Fall, dass es in der Klasse eine zusätzliche Logik gibt, die einige Tests in Anspruch nehmen könnte die Zukunft.

2) Ist es möglich, Tests einzurichten, die sich auf mehrere (nicht verspottete) Abhängigkeiten gleichzeitig stützen? Ich verstehe, dass dies technisch gesehen kein Unit-Test ist (Integrationstest vielleicht?), Aber ich vermute, dass es mit PHPUnit immer noch perfekt machbar ist. Anhand des obigen Beispiels möchte ich in der Lage sein, einen Test einzurichten, der nicht nur House, Door, Knob und HouseFactory isoliert testet, sondern auch die Ergebnisse der Interaktion der realen Objekte miteinander, möglicherweise mit einigen von ihnen Funktionen verspottet, wie diejenigen, die sich mit Daten befassen. Ist PHPUnit eine schlechte Wahl für diese Art von Tests?

Vielen Dank im Voraus für Ihre Zeit. Mir ist klar, dass einige der Annahmen, die ich mache, möglicherweise nicht richtig sind, da ich offensichtlich kein Experte in dieser Angelegenheit bin. Korrekturen sind willkommen und erwünscht.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage