it-swarm.com.de

Abstrakte Klassen testen

Wie teste ich die konkreten Methoden einer abstrakten Klasse mit PHPUnit?

Ich würde erwarten, dass ich im Rahmen des Tests eine Art Objekt erstellen muss. Ich habe jedoch keine Ahnung, wie dies am besten funktioniert oder ob PHPUnit dies zulässt.

137
Mez

Das Testen von Einheiten für abstrakte Klassen bedeutet nicht, dass die Schnittstelle getestet werden muss, da abstrakte Klassen konkrete Methoden haben können, und diese konkreten Methoden können getestet werden.

Es ist nicht ungewöhnlich, dass Sie beim Schreiben von Bibliothekscode eine bestimmte Basisklasse haben, die Sie in Ihrer Anwendungsebene erweitern möchten. Und wenn Sie sicherstellen möchten, dass Bibliothekscode getestet wird, benötigen Sie Mittel, um UT die konkreten Methoden abstrakter Klassen zu definieren.

Persönlich benutze ich PHPUnit, und es hat sogenannte Stubs und Mock-Objekte, um Ihnen beim Testen dieser Art von Dingen zu helfen.

Direkt aus PHPUnit-Handbuch :

abstract class AbstractClass
{
    public function concreteMethod()
    {
        return $this->abstractMethod();
    }

    public abstract function abstractMethod();
}

class AbstractClassTest extends PHPUnit_Framework_TestCase
{
    public function testConcreteMethod()
    {
        $stub = $this->getMockForAbstractClass('AbstractClass');
        $stub->expects($this->any())
             ->method('abstractMethod')
             ->will($this->returnValue(TRUE));

        $this->assertTrue($stub->concreteMethod());
    }
}

Mock Objekt gibt Ihnen mehrere Dinge:

  • sie müssen keine konkrete Implementierung der abstrakten Klasse haben und können stattdessen mit Stub davonkommen
  • sie können konkrete Methoden aufrufen und behaupten, dass sie korrekt ausgeführt werden
  • wenn sich eine konkrete Methode auf eine nicht implementierte (abstrakte) Methode stützt, können Sie den Rückgabewert mit der will () - PHPUnit-Methode löschen
230

Das ist eine gute Frage. Ich habe auch danach gesucht.
Glücklicherweise verfügt PHPUnit für diesen Fall bereits über die Methode getMockForAbstractClass() , z.

protected function setUp()
{
    $stub = $this->getMockForAbstractClass('Some_Abstract_Class');
    $this->_object = $stub;
}

Wichtig:

Beachten Sie, dass hierfür PHPUnit> 3.5.4 erforderlich ist. In früheren Versionen gab es einen Fehler .

So aktualisieren Sie auf die neueste Version:

Sudo pear channel-update pear.phpunit.de
Sudo pear upgrade phpunit/PHPUnit
36
takeshin

Es sollte beachtet werden, dass ab PHP 7 Unterstützung für anonyme Klassen hinzugefügt wurde. Dies gibt Ihnen eine zusätzliche Möglichkeit zum Einrichten eines Tests für eine abstrakte Klasse, eine Das hängt nicht von PHPUnit-spezifischen Funktionen ab.

class AbstractClassTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var AbstractClass
     */
    private $testedClass;

    public function setUp()
    {
        $this->testedClass = new class extends AbstractClass {

            protected function abstractMethod()
            {
                // Put a barebones implementation here
            }
        };
    }

    // Put your tests here
}
25
GordonM

Eran, Ihre Methode sollte funktionieren, aber sie widerspricht der Tendenz, den Test vor dem eigentlichen Code zu schreiben.

Ich würde vorschlagen, Ihre Tests für die gewünschte Funktionalität einer nicht abstrakten Unterklasse der fraglichen abstrakten Klasse zu schreiben, dann sowohl die abstrakte Klasse als auch die implementierende Unterklasse zu schreiben und schließlich den Test auszuführen.

Ihre Tests sollten natürlich die definierten Methoden der abstrakten Klasse testen, aber immer über die Unterklasse.

1
Bruno

Nelsons Antwort ist falsch.

Abstrakte Klassen erfordern nicht, dass alle Methoden abstrakt sind.

Die implementierten Methoden müssen getestet werden.

Sie können eine gefälschte Stub-Klasse in der Unit-Test-Datei erstellen, die abstrakte Klasse erweitern und natürlich nur das implementieren, was überhaupt nicht benötigt wird, und das testen.

Prost.

1
skqr

Wenn Sie die abstrakte Klasse nicht in Unterklassen unterteilen möchten, nur um einen Komponententest für die Methoden durchzuführen, die bereits in der abstrakten Klasse implementiert sind, können Sie versuchen, herauszufinden, ob Ihr Framework die Verwendung von mock abstrakten Klassen zulässt.

0
hangy