3 Stimmen

phpunit abstrakte Klasse constant

Ich versuche, einen Weg zu finden, um eine abstrakte Klasse Konstante zu testen, die vorhanden sein muss und übereinstimmen/nicht übereinstimmen einen Wert. Beispiel:

// to be extended by ExternalSDKClild
abstract class ExternalSDK {
    const VERSION = '3.1.1.'; 
}

class foo extends AController {
    public function init() {   
        if ( ExternalSDK::VERSION !== '3.1.1' ) {
            throw new Exception('Wrong ExternalSDK version!');
        }

        $this->setExternalSDKChild(new ExternalSDKChild());
    }
}

Beschränkungen... Das von uns verwendete Framework erlaubt keine Dependency Injection in der init()-Methode. (Vorschlag, die init()-Methode zu refaktorisieren, könnte der richtige Weg sein...)

Die Unit-Tests und die Codeabdeckung, die ich durchgeführt habe, decken alle außer der Exception ab. Ich kann nicht herausfinden, einen Weg, um die ExternalSDK::Version anders als was es ist zu sein.

Alle Gedanken sind willkommen

1voto

David Harkness Punkte 34750

Überarbeiten Sie zunächst den Aufruf von new in eine separate Methode.

Zweitens: Fügen Sie eine Methode hinzu, um die Version zu ermitteln, anstatt direkt auf die Konstante zuzugreifen. Klassenkonstanten in PHP werden beim Parsen in die Datei kompiliert und können nicht geändert werden.* Da auf sie statisch zugegriffen wird, gibt es keine Möglichkeit, sie zu überschreiben, ohne eine andere Klassendeklaration mit demselben Namen einzubauen. Die einzige Möglichkeit, dies mit Standard-PHP zu tun, besteht darin, den Test in einem separaten Prozess auszuführen, was sehr teuer ist.

class ExternalSDK {
    const VERSION = '3.1.1';

    public function getVersion() {
        return static::VERSION;
    }
}

class foo extends AController {
    public function init() {
        $sdk = $this->createSDK();
        if ( $sdk->getVersion() !== '3.1.1' ) {
            throw new Exception('Wrong ExternalSDK version!');
        }

        $this->setExternalSDKChild($sdk);
    }

    public function createSDK() {
        return new ExternalSDKChild();
    }
}

Und nun zum Einheitstest.

class NewerSDK extends ExternalSDK {
    const VERSION = '3.1.2';
}

/**
 * @expectedException Exception
 */
function testInitFailsWhenVersionIsDifferent() {
    $sdk = new NewerSDK();
    $foo = $this->getMock('foo', array('createSDK'));
    $foo->expects($this->once())
        ->method('createSDK')
        ->will($this->returnValue($sdk));
    $foo->init();
}

* Runkit bietet runkit_constant_redefine() was hier funktionieren könnte. Sie müssen die Ausnahme manuell abfangen, anstatt mit @expectedException damit Sie die Konstante wieder auf den richtigen Wert zurücksetzen können. Oder Sie können dies in tearDown() .

function testInitFailsWhenVersionIsDifferent() {
    try {
        runkit_constant_redefine('ExternalSDK::VERSION', '3.1.0');
        $foo = new foo();
        $foo->init();
        $failed = true;
    }
    catch (Exception $e) {
        $failed = false;
    }
    runkit_constant_redefine('ExternalSDK::VERSION', '3.1.1');
    if ($failed) {
        self::fail('Failed to detect incorrect SDK version.');
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X