Come testare i metodi concreti di una classe astratta con PHPUnit?
Mi aspetto che dovrei creare una sorta di oggetto come parte del test. Tuttavia, non ho idea delle migliori pratiche per questo o se PHPUnit lo consente.
Come testare i metodi concreti di una classe astratta con PHPUnit?
Mi aspetto che dovrei creare una sorta di oggetto come parte del test. Tuttavia, non ho idea delle migliori pratiche per questo o se PHPUnit lo consente.
Risposte:
Il test unitario di classi astratte non significa necessariamente testare l'interfaccia, poiché le classi astratte possono avere metodi concreti e questi metodi concreti possono essere testati.
Non è così raro, quando si scrive un codice libreria, avere una certa classe base che si prevede di estendere nel livello dell'applicazione. E se vuoi assicurarti che il codice della libreria sia testato, hai bisogno di mezzi per UT i metodi concreti delle classi astratte.
Personalmente, utilizzo PHPUnit e ha i cosiddetti stub e oggetti finti per aiutarti a testare questo tipo di cose.
Direttamente dal manuale di 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());
}
}
L'oggetto finto ti dà diverse cose:
Questa è una buona domanda. Ho cercato anche questo.
Fortunatamente, PHPUnit ha già un getMockForAbstractClass()
metodo per questo caso, ad es
protected function setUp()
{
$stub = $this->getMockForAbstractClass('Some_Abstract_Class');
$this->_object = $stub;
}
Nota che ciò richiede PHPUnit> 3.5.4. Si è verificato un errore nelle versioni precedenti.
Per eseguire l'aggiornamento alla versione più recente:
sudo pear channel-update pear.phpunit.de
sudo pear upgrade phpunit/PHPUnit
Va notato che a partire dal PHP 7 è stato aggiunto il supporto per le classi anonime . Questo ti dà una strada aggiuntiva per impostare un test per una classe astratta, che non dipende dalla funzionalità specifica di 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
}
Ehi, il tuo metodo dovrebbe funzionare, ma va contro la tendenza a scrivere il test prima del codice reale.
Quello che suggerirei è di scrivere i tuoi test sulla funzionalità desiderata di una sottoclasse non astratta della classe astratta in questione, quindi scrivere sia la classe astratta che la sottoclasse di implementazione, ed infine eseguire il test.
I tuoi test dovrebbero ovviamente testare i metodi definiti della classe astratta, ma sempre tramite la sottoclasse.
La risposta di Nelson è sbagliata.
Le classi astratte non richiedono che tutti i loro metodi siano astratti.
I metodi implementati sono quelli che dobbiamo testare.
Quello che puoi fare è creare una classe stub falsa sul file di test unitario, estenderla alla classe astratta e implementare solo ciò che è richiesto senza alcuna funzionalità, ovviamente, e testarlo.
Saluti.