Pregunta

¿Cómo pruebo los métodos concretos de una clase abstracta con PHPUnit?

Esperaría tener que crear algún tipo de objeto como parte de la prueba. Sin embargo, no tengo idea de la mejor práctica para esto o si PHPUnit lo permite.

¿Fue útil?

Solución

Las pruebas unitarias de clases abstractas no necesariamente significan probar la interfaz, ya que las clases abstractas pueden tener métodos concretos, y estos métodos concretos pueden ser probados.

No es tan raro, cuando se escribe un código de biblioteca, tener cierta clase base que espera extender en su capa de aplicación. Y si desea asegurarse de que se prueba el código de la biblioteca, necesita medios para UT los métodos concretos de clases abstractas.

Personalmente, uso PHPUnit, y tiene los llamados trozos y objetos simulados para ayudarte a probar este tipo de cosas.

Directamente desde PHPUnit manual :

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());
    }
}

El objeto simulado te ofrece varias cosas:

  • no es necesario que tengas una implementación concreta de la clase abstracta, y puedes salirte con el código auxiliar en su lugar
  • puede llamar a métodos concretos y afirmar que funcionan correctamente
  • si el método concreto se basa en el método no implementado (abstracto), puede tropezar el valor de retorno con el método will () PHPUnit

Otros consejos

Esa es una buena pregunta. He estado buscando esto también.
Afortunadamente, PHPUnit ya tiene método getMockForAbstractClass () para este caso, p. ej.

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

Importante:

Tenga en cuenta que esto requiere PHPUnit > 3.5.4. Hubo un error en versiones anteriores.

Para actualizar a la versión más reciente:

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

Cabe señalar que a partir de la compatibilidad con PHP 7 para clases anónimas ha sido añadido. Esto le brinda una vía adicional para configurar una prueba para una clase abstracta, una que no depende de la funcionalidad específica de PHPUnit.

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, tu método debería funcionar, pero va en contra de la tendencia de escribir la prueba antes del código real.

Lo que sugeriría es que escriba sus pruebas sobre la funcionalidad deseada de una subclase no abstracta de la clase abstracta en cuestión, luego escriba tanto la clase abstracta como la subclase de implementación, y finalmente ejecute la prueba.

Sus pruebas obviamente deberían probar los métodos definidos de la clase abstracta, pero siempre a través de la subclase.

La respuesta de Nelson es incorrecta.

Las clases abstractas no requieren que todos sus métodos sean abstractos.

Los métodos implementados son los que necesitamos probar.

Lo que puede hacer es crear una clase de código auxiliar falso en el archivo de prueba de la unidad, hacer que extienda la clase abstracta e implementar solo lo que se requiere sin ninguna funcionalidad, por supuesto, y probarlo.

Saludos.

Si no desea subclasificar la clase abstracta solo para realizar una prueba unitaria de los métodos que ya están implementados en la clase abstracta, puede intentar ver si su marco le permite simulacro clases abstractas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top