Phpunit: assertType() invoquant le chargeur automatique pour les types scalaires

Créé le 23 nov. 2010  ·  10Commentaires  ·  Source: sebastianbergmann/phpunit

Lorsque vous utilisez assertType() pour vérifier si une valeur est un tableau ou une valeur scalaire, le chargeur automatique est appelé (comme effet secondaire de l'utilisation de class_exists()). Il serait bon de vérifier si le paramètre de chaîne de type attendu correspond d'abord à "tableau" ou à un type scalaire.

Exemple:

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

Attendu : vrai, sans appeler le chargeur automatique
Réel : vrai, appelant le chargeur automatique pour une classe nommée "tableau"

Commentaire le plus utile

Veuillez utiliser assertInternalType() au lieu de assertType() pour les types internes.

Tous les 10 commentaires

Veuillez utiliser assertInternalType() au lieu de assertType() pour les types internes.

Cela fonctionne, mais pourquoi est-ce nécessaire?

Voici le code de 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)
                );
            }

Il me semble que PHPUnit_Util_Type::isType teste déjà si le type est un type interne, donc tout ce que vous auriez à changer est ceci :

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

pour désactiver le chargeur automatique pour les types internes. Qu'est-ce que je rate?

Je suis d'accord avec arnoschaefer, pourquoi exigez-vous que nous utilisions une fonction différente alors que sa solution suffit ? Je ne change pas des milliers de tests unitaires déjà en place qui utilisent assertType depuis < 3.5. Je vais donc remplacer assertType pour tous mes tests unitaires avec cette solution. Je pense que nous méritons une meilleure explication pourquoi vous avez choisi ce chemin sinon je vais devoir déclarer phpunit FAIL.

Une seule méthode d'acquisition ne peut pas implémenter les deux fonctionnalités différentes. C'était mon erreur de supposer initialement que c'était possible. C'est pourquoi assertInternalType() existe maintenant.

Veuillez expliquer pourquoi une seule méthode d'assertion ne peut pas implémenter les deux fonctionnalités différentes ?

De plus, votre documentation contredit cette affirmation :

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

Alternativement, $expected peut être l'une de ces constantes pour indiquer un type interne :

* 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")

Votre note ci-dessous "recommande" uniquement d'utiliser assertInternalType et qu'il n'est pas obligatoire :

Noter

Il est recommandé d'utiliser assertInternalType (voir la section intitulée « assertInternalType() ») à la place pour vérifier les types internes.

Une seule méthode d'assertion ne peut pas implémenter les deux fonctionnalités différentes car elles sont ambiguës. Disons que vous avez une classe nommée String et que vous utilisez assertType("string", ...) -- comment PHPUnit est-il censé savoir ce que vous voulez ?

La recommandation concerne exactement le cas que vous rencontrez : vous utilisez un chargeur automatique et souhaitez utiliser assertType() . Cela ne fonctionne pas.

Alors que php permet à une classe d'être appelée entier ou chaîne, votre code ne permet actuellement pas à une classe d'être appelée chaîne, entier, etc., car cela lèverait une exception d'argument non valide (%s est ambigu).

Le problème est que si vous ne définissez pas le paramètre autoload sur false dans les fonctions class_exists et interface_exists à la ligne 1208, l'autoloader tentera d'inclure un fichier qui n'existe pas (par exemple class.array.php) et lancera une erreur php au lieu d'une exception.

Faire cette modification permettra à assertType d'être utilisé comme il l'a toujours été.

Non, ce ne sera pas le cas. Parce qu'alors d'autres personnes crieront après moi / PHPUnit parce qu'ils s'attendent à ce que le chargement automatique charge automatiquement leur classe String .

Voici mon conseil, à prendre ou à laisser :

N'utilisez pas assertType() . Il est obsolète (bien que j'ai oublié de le marquer comme tel) et finira par disparaître. Il n'existe que dans les versions actuelles de PHPUnit pour faciliter la migration.

Utilisez assertInternalType() pour affirmer qu'une variable a un type interne spécifié.

Utilisez assertInstanceOf() pour affirmer qu'un objet a un type spécifié (classe ou interface).

Je n'ai aucun problème avec une fonction obsolète, mais vous ne facilitez pas du tout la migration. Vous avez modifié la fonctionnalité d'origine de phpunit 3.4 qui n'avait pas cette exception en premier lieu et qui casse maintenant mon code au lieu du gars qui charge automatiquement la classe String. Je pense donc que vous devriez soit le supprimer complètement dans phpunit 3.5, soit le rétablir à la fonctionnalité 3.4.

Installez-vous, inutile de vous énerver. Pour ma part, je peux vivre avec la décision de Sebastian, cela a du sens, c'est juste bon de connaître la raison derrière cela. J'utiliserai donc les deux autres fonctions à l'avenir. D'un autre côté, si assertType est de toute façon obsolète, pourquoi ne pas le laisser fonctionner comme avant et documenter clairement qu'il est obsolète, sous réserve de suppression dans le futur. Mais c'est bien sûr la décision de Sebastian, car c'est la voie du logiciel libre.

Cette page vous a été utile?
0 / 5 - 0 notes