Como testar 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 o PHPUnit permitir isso.
Como testar 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 o PHPUnit permitir isso.
Respostas:
O teste de unidade de classes abstratas não significa necessário 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 um código de biblioteca, ter certa classe base que você espera estender na camada de aplicativos. E se você quiser garantir que o código da biblioteca seja testado, precisará de meios para UT os métodos concretos das classes abstratas.
Pessoalmente, eu uso o PHPUnit e ele chama stubs e objetos simulados para ajudá-lo a testar esse tipo de coisa.
Diretamente do manual do 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());
}
}
O objeto simulado oferece várias coisas:
Esta é uma boa pergunta. Eu também estava procurando por isso.
Felizmente, o PHPUnit já possui um getMockForAbstractClass()
método para este caso, por exemplo
protected function setUp()
{
$stub = $this->getMockForAbstractClass('Some_Abstract_Class');
$this->_object = $stub;
}
Note que isso requer PHPUnit> 3.5.4. Houve um erro nas 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 PHP 7 , foi adicionado suporte para classes anônimas . Isso fornece 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 na funcionalidade desejada de uma subclasse não abstrata da classe abstrata em questão, depois escrever a classe abstrata e a subclasse de implementação 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 da unidade, estender a classe abstrata e implementar apenas o necessário, sem nenhuma funcionalidade, é claro, e testá-lo.
Felicidades.