PHP Unittests: Wie teste ich mit Singletons?

Das Problem mit Singletons ist, dass sie eine statische Variable enthalten, die über verschiedene Tests hinweg erhalten bleibt. Dazu kommt, dass sie protected/private ist und somit nicht einfach zurück gesetzt werden kann. In diesem Beitrag werden wir sehen, wie wir der Sache beikommen können.


Was ist das Problem?

Normalerweise muss irgendein Teil der Applikation mit einem Mock ersetzt werden. Ist dies bei einem Singleton in einem Test erfolgt, kann man keine weiteren Mocks mehr einfügen, da die statische Variable, die die Instanz des Singletons enthält nicht zurück gesetzt wird.


Lösung

So läßt sich das Problem lösen:

Wir benutzen die setUp()-Methode um vor unserem Test sicher zu stellen, dass die Singleton-Instanz nicht vorhanden ist. Das ganze klappt auch in der tearDown(), aber ich konzentriere mich lieber auf saubere Ausgangsbedingungen, als nach einem Test aufzuräumen.
Zunächst wird die private statische Variable „$_instance“ mit setAccessible(true) für Zugriffe freigegeben und anschließend auf null gesetzt. Als erster Parameter von setValue() könnte ein konkretes Objekt angegeben werden, aber das haben wir hier ja nicht.


Alternative

Alternativ kann man auch mit der Kommandozeilenoption „–static-backup“ oder dem XML-Attribut backupStaticAttributes=“false“ für phpUnit dem Problem aus dem Weg gehen. Das gilt dann aber für alle Tests und ist möglicherweise nicht gewünscht.