Pergunta

Como testo os métodos concretos de uma classe abstrata com phpunit?

Eu esperaria que eu tivesse que criar algum tipo de objeto como parte do teste. No entanto, não faço ideia da melhor prática para isso ou se a phpunit permite isso.

Foi útil?

Solução

O teste de unidade de classes abstratas não significa testar a interface, pois as classes abstratas podem ter métodos concretos, e esses métodos concretos podem ser testados.

Não é tão incomum, ao escrever algum código da biblioteca, ter determinada classe base que você espera estender na camada de aplicativo. E se você deseja garantir que o código da biblioteca seja testado, precisa de meios para usar os métodos concretos de classes abstratas.

Pessoalmente, eu uso o Phpunit e tem o chamado Stubs e Mock Objects para ajudá -lo a testar esse tipo de coisa.

Direto de Manual de Phpunit:

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

Objeto simulado lhe dê várias coisas:

  • Você não é obrigado a ter uma implementação concreta de classe abstrata e pode se safar com o stub
  • Você pode chamar métodos concretos e afirmar que eles executam corretamente
  • Se o método concreto depende do método não implementado (resumo), você poderá extrair o valor de retorno com o método de Will () Phpunit

Outras dicas

Esta é uma boa pergunta. Eu tenho procurado por isso também.
Felizmente, Phpunit já tem getMockForAbstractClass() método para este caso, por exemplo

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

Importante:

Observe que isso requer phpunit> 3.5.4. Houve um inseto em versões anteriores.

Para atualizar para a versão mais recente:

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

Deve -se notar que a partir do suporte do Php 7 para Aulas anônimas foi adicionado. Isso oferece uma avenida adicional para a configuração de um teste para uma classe abstrata, que não depende da funcionalidade específica do 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, seu método deve funcionar, mas vai contra a tendência de escrever o teste antes do código real.

O que eu sugeriria é escrever seus testes sobre a funcionalidade desejada de uma subclasse não abstratada da classe abstrata em questão, depois escrever a classe abstrata e a subclasse implementadora e, finalmente, executar o teste.

Seus testes devem obviamente testar os métodos definidos da classe abstrata, mas sempre através da subclasse.

A resposta de Nelson está errada.

As classes abstratas não exigem que todos os seus métodos sejam abstratos.

Os métodos implementados são os que precisamos testar.

O que você pode fazer é criar uma classe de stub falsa no arquivo de teste de unidade, estender a classe abstrata e implementar apenas o que é necessário sem nenhuma funcionalidade, é claro, e testá -la.

Felicidades.

Se você não deseja subclasse a classe abstrata apenas para realizar um teste de unidade nos métodos que já são implementados na classe abstrata, você pode tentar ver se sua estrutura permite que você zombar Classes abstratas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top