Phpunit: assertType() ruft Autoloader für skalare Typen auf

Erstellt am 23. Nov. 2010  ·  10Kommentare  ·  Quelle: sebastianbergmann/phpunit

Wenn Sie mit assertType() prüfen, ob ein Wert ein Array oder ein Skalarwert ist, wird der Autoloader aufgerufen (als Nebeneffekt der Verwendung von class_exists()). Es wäre schön zu prüfen, ob der erwartete Typ-String-Parameter zuerst mit "Array" oder einem skalaren Typ übereinstimmt.

Beispiel:

$this->assertType('array', array());

Erwartet: true, ohne den Autoloader aufzurufen
Tatsächlich: wahr, ruft den Autoloader für eine Klasse namens „array“ auf

Hilfreichster Kommentar

Bitte verwenden Sie assertInternalType() anstelle von assertType() für interne Typen.

Alle 10 Kommentare

Bitte verwenden Sie assertInternalType() anstelle von assertType() für interne Typen.

Das geht, aber warum ist das nötig?

Hier ist der Code von assertType:

public static function assertType($expected, $actual, $message = '')
{
    if (is_string($expected)) {
        if (PHPUnit_Util_Type::isType($expected)) {
            if (class_exists($expected) || interface_exists($expected)) {
                throw new InvalidArgumentException(
                  sprintf('"%s" is ambigious', $expected)
                );
            }

Es scheint mir, dass PHPUnit_Util_Type::isType bereits testet, ob der Typ ein interner Typ ist, also müssten Sie nur Folgendes ändern:

            if (class_exists($expected, false) || interface_exists($expected, false)) {

um den Autoloader für interne Typen zu deaktivieren. Was vermisse ich?

Ich muss Arnoschaefer zustimmen, warum verlangen Sie, dass wir eine andere Funktion verwenden, wenn seine Lösung ausreicht? Ich ändere nicht Tausende von bereits vorhandenen Unit-Tests, die AssertType aus < 3.5 verwenden. Daher werde ich mit dieser Lösung assertType für alle meine Komponententests überschreiben. Ich denke, wir verdienen eine bessere Erklärung, warum Sie diesen Weg gewählt haben, sonst muss ich phpunit für FAIL erklären.

Eine einzelne Asset-Methode kann die beiden unterschiedlichen Funktionalitäten nicht implementieren. Es war mein Fehler, anfangs anzunehmen, dass es möglich wäre. Aus diesem Grund existiert jetzt assertInternalType() .

Bitte erläutern Sie, warum eine einzelne Assertion-Methode die beiden unterschiedlichen Funktionalitäten nicht implementieren kann.

Außerdem widerspricht Ihre Dokumentation dieser Aussage:

http://www.phpunit.de/manual/3.5/en/api.html#api.assert.assertType :

Alternativ kann $erwartet eine dieser Konstanten sein, um einen internen Typ anzugeben:

* PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY ("array")
* PHPUnit_Framework_Constraint_IsType::TYPE_BOOL ("bool")
* PHPUnit_Framework_Constraint_IsType::TYPE_FLOAT ("float")
* PHPUnit_Framework_Constraint_IsType::TYPE_INT ("int")
* PHPUnit_Framework_Constraint_IsType::TYPE_NULL ("null")
* PHPUnit_Framework_Constraint_IsType::TYPE_NUMERIC ("numeric")
* PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT ("object")
* PHPUnit_Framework_Constraint_IsType::TYPE_RESOURCE ("resource")
* PHPUnit_Framework_Constraint_IsType::TYPE_STRING ("string")

Ihr Hinweis unten "empfiehlt" nur, dass assertInternalType verwendet werden sollte und dass es nicht erforderlich ist:

Notiz

Es wird empfohlen, stattdessen assertInternalType (siehe „assertInternalType()“) zu verwenden, um nach internen Typen zu suchen.

Eine einzelne Behauptungsmethode kann die zwei unterschiedlichen Funktionalitäten nicht implementieren, da sie mehrdeutig sind. Angenommen, Sie haben eine Klasse namens String und verwenden assertType("string", ...) – woher soll PHPUnit wissen, was Sie wollen?

Die Empfehlung ist genau für den Fall, den Sie erleben: Sie verwenden einen Autoloader und möchten assertType() verwenden. Das funktioniert nicht.

Während PHP es zulässt, dass eine Klasse Integer oder String genannt wird, erlaubt Ihr Code derzeit nicht, dass eine Klasse als String, Integer usw. bezeichnet wird, da dies eine Ausnahme für ein ungültiges Argument (%s ist mehrdeutig) auslösen würde.

Das Problem ist, dass, wenn Sie den Parameter autoload in den Funktionen class_exists und interface_exists in Zeile 1208 nicht auf false setzen, der Autoloader versucht, eine Datei einzuschließen, die nicht existiert (z. B. class.array.php), und einen PHP-Fehler ausgibt statt einer Ausnahme.

Wenn Sie diese Änderung vornehmen, kann assertType so verwendet werden, wie es immer war.

Nein, das wird es nicht. Denn dann werden andere Leute mich / PHPUnit anschreien, weil sie erwarten, dass der Autoload ihre Klasse String automatisch lädt.

Hier ist mein Rat, nimm es an oder lass es:

Verwenden Sie nicht assertType() . Es ist veraltet (obwohl ich vergessen habe, es als solches zu markieren) und wird irgendwann verschwinden. Es existiert nur in aktuellen Versionen von PHPUnit, um die Migration zu erleichtern.

Verwenden Sie assertInternalType() , um zu bestätigen, dass eine Variable einen bestimmten internen Typ hat.

Verwenden Sie assertInstanceOf() , um zu bestätigen, dass ein Objekt einen bestimmten Typ hat (Klasse oder Schnittstelle).

Ich habe keine Probleme mit einer veralteten Funktion, aber Sie erleichtern die Migration überhaupt nicht. Sie haben die ursprüngliche Funktionalität von phpunit 3.4 geändert, die diese Ausnahme überhaupt nicht hatte, und bricht jetzt meinen Code anstelle des Typs, der die String-Klasse automatisch lädt. Ich denke also, Sie sollten es entweder vollständig in phpunit 3.5 entfernen oder es auf die 3.4-Funktionalität zurücksetzen.

Beruhigen Sie sich, es gibt keinen Grund, sich aufzuregen. Ich für meinen Teil kann mit Sebastians Entscheidung leben, es macht tatsächlich Sinn, es ist einfach gut, die Gründe dafür zu kennen. Daher werde ich in Zukunft die beiden anderen Funktionen verwenden. Auf der anderen Seite, wenn assertType sowieso veraltet ist, warum sollte es nicht so funktionieren wie zuvor und klar dokumentieren, dass es veraltet ist, vorbehaltlich einer Entfernung irgendwann in der Zukunft. Aber das ist natürlich Sebastians Entscheidung, denn das ist der Weg freier Software.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen