Frage

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

Ich würde erwarten, dass ich als Teil des Tests eine Art Objekt erstellen müsste. Ich habe jedoch keine Ahnung, wie bester Praxis dafür oder wenn Phpunit dies zulässt.

War es hilfreich?

Lösung

Unit -Tests von abstrakten Klassen bedeutet nicht erforderlich, die Schnittstelle zu testen, da abstrakte Klassen konkrete Methoden haben können und diese konkreten Methoden getestet werden können.

Beim Schreiben eines Bibliothekscodes ist es nicht so ungewöhnlich, eine bestimmte Basisklasse zu haben, die Sie in Ihrer Anwendungsschicht erwarten. Und wenn Sie sicherstellen möchten, dass der Bibliothekscode getestet wird, benötigen Sie Mittel, um die konkreten Methoden der abstrakten Klassen zu entsprechen.

Persönlich verwende ich Phpunit und es hat so genannte Stubs und Scheinobjekte, um Ihnen dabei zu helfen, solche Dinge zu testen.

Direkt von 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 geben 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 ausführen
  • Wenn die konkrete Methode auf eine nicht implementierte (abstrakte) Methode angewiesen ist, können Sie den Rückgabewert mit Will () Phpunit -Methode stoßen

Andere Tipps

Das ist eine gute Frage. Ich habe auch danach gesucht.
Zum Glück hat Phpunit bereits getMockForAbstractClass() Methode für diesen Fall, z. B.

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

Wichtig:

Beachten Sie, dass dies Phpunit> 3.5.4 erfordert. Dort war ein Käfer in früheren Versionen.

Upgrade auf die neueste Version:

sudo pear channel-update pear.phpunit.de
sudo pear upgrade phpunit/PHPUnit

Es sollte beachtet werden, dass ab Php 7 Unterstützung für Anonyme Klassen wurde hinzugefügt. Auf diese Weise erhalten Sie einen zusätzlichen Weg zum Einrichten eines Tests für eine abstrakte Klasse, die nicht von der phpunit-spezifischen Funktionalität abhängt.

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
}

Eran, Ihre Methode sollte funktionieren, aber sie verstößt gegen die Tendenz, den Test vor dem tatsächlichen Code zu schreiben.

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

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

Nelsons Antwort ist falsch.

Abstrakte Klassen erfordern nicht alle ihre Methoden, um abstrakt zu sein.

Die implementierten Methoden sind diejenigen, die wir testen müssen.

Sie können eine gefälschte Stub -Klasse in der Unit -Testdatei erstellen, die abstrakte Klasse erweitern und nur das implementieren, was erforderlich ist, ohne dass überhaupt keine Funktionalität ist, und dies zu testen.

Prost.

Wenn Sie die abstrakte Klasse nicht unterschreiben möchten, nur um einen Unit -Test für die Methoden durchzuführen, die bereits in der abstrakten Klasse implementiert sind, können Sie versuchen, festzustellen, ob Ihr Framework Ihnen zu ermöglicht spotten Abstrakte Klassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top