Es gibt Webdeveloper die sagen, daß es nur nötig ist public Methoden einer PHP-Klasse zu testen. Die Meinung kann man auch durchaus vertreten. Testet man die werden wahrscheinlich alle anderen, also private- oder protected-Methoden mitgetestet.
Sollte das nicht der Fall sein, werden sie einfach nicht gebraucht. Wenn wir jetzt mal vom extrem ausgehen und sagen es gibt nur eine public und eine protected Methode, wird die protected-Methode mit abgedeckt. Da sie entweder im Constructor oder der Methode verwendet wird. Legt man explizit noch einen Test für die protected Methode an testet man also doppelt. Das soll vermieden werden. Ansichtssache finde ich. Man testet ja das Unit, also die Einheit. Ein solcher fehlgeschlagener Unittest gibt einen dann mehr Auskunft über die Fehlerquelle. Ich persönlich finde das komfortabler. Um mit Phpunit protected private Methoden oder auch Attribute zu testen benötigt man eine Reflection Class.
Phpunit protected private method
Hier abgebildet ist jetzt eine invoke-Methode mit der ich mit Phpunit protected oder auch private Methoden testen lassen. Es bietet sich an diese Methode in die bootstrap.php auszulagern und so für jeden Unittest zur Verfügung zu stellen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * Call protected/private method of a class. * * @param object &$object Instantiated object that we will run method on. * @param string $methodName Method name to call * @param array $parameters Array of parameters to pass into method. * * @return mixed Method return. */ public function invokeMethod(&$object, $methodName, array $parameters = array()) { $reflection = new \ReflectionClass(get_class($object)); $method = $reflection->getMethod($methodName); $method->setAccessible(TRUE); return $method->invokeArgs($object, $parameters); } |
Im Grunde ist ja dem Phpdoc schon alles entnehmen. Der erste Parameter ist in diesem Fall das Object bzw. die zu testende Klasse. Der zweite Parameter ist der Name der Methode und dann muß ggf. noch der nötige Parameter als Array übergeben werden.
Phpunit protected private Attribut
Der nachfolgende Code gibt einen Zugriff mit Phpunit auf protected oder private Attribute. Damit kann man natürlich auch __constructor Auswirkung testen. Zudem werden natürlich auch in vielen Methoden die Attribute gesetzt und dann in der Klasse intern verwendet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * Call protected/private method of a class. * * @param object $object Instantiated object that we will run method on. * @param string $attributeName Attribute name to call. * * @return mixed Method return. */ public function invokeAttribute(&$object, $attributeName) { $r = new \ReflectionClass($object); $attribute = $r->getProperty($attributeName); $attribute->setAccessible(TRUE); return $attribute->getValue($object); } |
Hier ist im Grunde alles, wie bei der invoke-Methode um auf eine Methode zuzugreifen. Nur das hier der Value eines Attributes zurück gegeben wird.
Phpunit set private protected Attribute
Zu guter letzt kann man mit dieser invoke-Methode in dem Test protected und private Attribute setzen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/** * Set protected/private attribute. * * @param string $property Name of the property. * @param mixed $value Value of the property. */ public function setProtectedAttribute($property, $value) { $reflection = new ReflectionClass($this->fixture); $reflection_property = $reflection->getProperty($property); $reflection_property->setAccessible(TRUE); $reflection_property->setValue($this->fixture, $value); } |