Phpunit: assertType () invocando el autocargador para tipos escalares

Creado en 23 nov. 2010  ·  10Comentarios  ·  Fuente: sebastianbergmann/phpunit

Cuando se usa assertType() para verificar si un valor es una matriz o un valor escalar, se invoca el cargador automático (como efecto secundario de usar class_exists()). Sería bueno verificar si el parámetro de cadena de tipo esperado coincide con "matriz" o un tipo escalar primero.

Ejemplo:

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

Esperado: verdadero, sin invocar el cargador automático
Real: verdadero, invocando el cargador automático para una clase llamada "matriz"

Comentario más útil

Utilice assertInternalType() en lugar de assertType() para tipos internos.

Todos 10 comentarios

Utilice assertInternalType() en lugar de assertType() para tipos internos.

Eso funciona, pero ¿por qué es necesario?

Aquí está el código 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)
                );
            }

Me parece que PHPUnit_Util_Type::isType ya prueba si el tipo es un tipo interno, por lo que todo lo que tendría que cambiar es esto:

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

para deshabilitar el autocargador para tipos internos. ¿Qué me estoy perdiendo?

Tengo que estar de acuerdo con arnoschaefer, ¿por qué requiere que usemos una función diferente cuando su solución es suficiente? No estoy cambiando miles de pruebas unitarias que ya están en su lugar y que usan asertType desde < 3.5. Así que anularé assertType para todas mis pruebas unitarias con esta solución. Creo que merecemos una mejor explicación de por qué eligió este camino; de lo contrario, tendré que declarar phpunit FAIL.

Un solo método de activo no puede implementar las dos funcionalidades diferentes. Fue mi error asumir inicialmente que era posible. Es por eso que assertInternalType() existe ahora.

Proporcione una explicación de por qué un solo método de aserción no puede implementar las dos funcionalidades diferentes.

Además, su documentación contradice esta declaración:

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

Alternativamente, $esperado puede ser una de estas constantes para indicar un tipo interno:

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

Su nota a continuación solo "recomienda" que se debe usar assertInternalType y que no es obligatorio:

Nota

Se recomienda usar assertInternalType (consulte la sección llamada "assertInternalType()") en lugar de verificar los tipos internos.

Un solo método de aserción no puede implementar las dos funcionalidades diferentes porque son ambiguas. Digamos que tiene una clase llamada String y usa assertType("string", ...) -- ¿cómo se supone que PHPUnit sabe qué es lo que quiere?

La recomendación es exactamente para el caso que está experimentando: está utilizando un cargador automático y desea utilizar assertType() . Eso no funciona.

Si bien php permite que una clase se llame entero o cadena, su código actualmente no permite que una clase se llame cadena, entero, etc., ya que generaría una excepción de argumento no válido (%s es ambiguo).

El problema es que si no establece el parámetro de carga automática en falso en las funciones class_exists e interface_exists en la línea 1208, el cargador automático intentará incluir un archivo que no existe (por ejemplo, class.array.php) y generará un error de php. en lugar de una excepción.

Hacer esta modificación permitirá que assertType se use como siempre se ha hecho.

No, no lo hará. Porque entonces otras personas me gritarán / PHPUnit porque esperan que la carga automática cargue automáticamente su clase String .

Este es mi consejo, tómalo o déjalo:

No use assertType() . Está en desuso (aunque olvidé marcarlo como tal) y desaparecerá eventualmente. Solo existe en las versiones actuales de PHPUnit para facilitar la migración.

Use assertInternalType() para afirmar que una variable tiene un tipo interno específico.

Use assertInstanceOf() para afirmar que un objeto tiene un tipo específico (clase o interfaz).

No tengo problemas con una función obsoleta, pero no está facilitando la migración en absoluto. Ha cambiado la funcionalidad original de phpunit 3.4 que no tenía esta excepción en primer lugar y ahora está rompiendo mi código en lugar del tipo que carga automáticamente la clase String. Así que creo que debería eliminarlo por completo en phpunit 3.5 o revertirlo a la funcionalidad 3.4.

Cálmate, no hay necesidad de emocionarse. Por mi parte, puedo vivir con la decisión de Sebastian, en realidad tiene sentido, es bueno saber la razón detrás de esto. Así que usaré las otras dos funciones en el futuro. Por otro lado, si de todos modos asertType está en desuso, ¿por qué no mantenerlo funcionando como lo hacía antes y documentar claramente que está en desuso, sujeto a eliminación en el futuro? Pero esa es, por supuesto, la decisión de Sebastian, ya que este es el camino del software libre.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

joubertredrat picture joubertredrat  ·  4Comentarios

keradus picture keradus  ·  4Comentarios

rentalhost picture rentalhost  ·  4Comentarios

stephen-leavitt-sonyatv-com picture stephen-leavitt-sonyatv-com  ·  4Comentarios

stof picture stof  ·  3Comentarios