Domanda

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.

È stato utile?

Soluzione

Test di unità 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 è insolito, 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 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:

  • non è necessario avere un'implementazione concreta della classe astratta, e invece è possibile cavarsela con stub
  • puoi chiamare metodi concreti e affermare che funzionano correttamente
  • se il metodo concreto si basa su un metodo non implementato (astratto), è possibile stub il valore di ritorno con il metodo will () PHPUnit

Altri suggerimenti

Questa è una buona domanda. Ho cercato anche questo.
Fortunatamente, PHPUnit ha già metodo getMockForAbstractClass () per questo caso, ad esempio

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

Importante:

Nota che questo richiede PHPUnit > 3.5.4. C'era un bug 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 supporto di PHP 7 per classi anonime è stato aggiunto. 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
}

Eran, 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 in classe astratta e implementare solo ciò che è richiesto senza alcuna funzionalità, ovviamente, e testarlo.

Saluti.

Se non si desidera sottoclassare la classe astratta solo per eseguire un test unitario sui metodi che sono già implementati nella classe astratta, si potrebbe provare a vedere se il proprio framework consente di derisione classi astratte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top