Domanda

Ho guardato attraverso le varie domande sul test delle unità, ma non riesco a trovare uno che risponde specificamente a questa domanda.

Ho diverse classi PHP che contengono funzioni che assomigliano a questo:

    static function _setSuspended($Suspended, $UserID)
    {
        try {
            $con = Propel::getConnection();

            $c1 = new Criteria();
            $c1->add(DomainsPeer::USERID,$UserID);

            $update = new Criteria();
            $update->add(DomainsPeer::SUSPENDED,$Suspended);

            BasePeer::doUpdate($c1, $update, $con);

            return true;
        } catch(PropelException $e) {
            return $e->getMessage();
        }
    }

sto usando Propel come il mio ORM. Ho letto attraverso vari argomenti di unit test che parlano di creazione di 'Mocks' e 'stub' e non quello, ma non sono stato in grado di trovare tutto ciò che ti dice specificamente come testare una funzione come sopra.

Il mio pensiero va qualcosa come: ho bisogno di testare la funzione di cui sopra in modo da vorrei chiamarlo. Ma se lo chiamo io, si usa Propel come ORM e secondo i principi Unit Testing devo isolare ogni funzione di per sé.

io non vedo un modo per farlo. Che cosa mi manca qui?

È stato utile?

Soluzione

Ho trovato che beffardo l'ORM non mi dà alcuna fiducia perché la configurazione ORM non viene mai testato. ORM hanno anche un sacco di azione a distanza gli effetti che possono dare falsa confidenza con test di unità. Beffardo il driver di database o fornire un supplente database in memoria mi dà molto più elevato di fiducia il mio codice è corretto ed è circa duro come beffardo l'ORM.

SQLite è un grande database in memoria per i test di unità. E 'sulla lista di database supportati PDO. (DOP è il driver di database Propel 1.3.) Se non si desidera utilizzare un database in memoria, si potrebbe essere in grado di trovare un mock DOP già scritto.

Altri suggerimenti

Questa è una risposta generica che io non sono a conoscenza Propel a tutti e solo un po 'più familiarità con PHP. La risposta di base è che si utilizza l'iniezione di dipendenza. Invece di riferirsi direttamente al vostro ORM, si crea un involucro attorno ad esso, poi iniettare l'involucro nella tua classe / funzione di utilizzare effettivamente. Per fare test di unità, quindi si crea una versione finto o falso dell'involucro che non interfaccia con l'ORM, ma invece consente di configurare le risposte da parte del wrapper per le vostre chiamate di metodi. Questo ti permette di scomporre l'ORM quando l'unità verificare le proprie funzioni.

Stavo cercando di affrontare lo stesso problema, mentre la costruzione di una PHPUnit Plugin per Symfony . Ho finito si avvicina in modo simile a di Django di prova quadro -. utilizzare un database / connessione separata, e distruggere e ricostruire prima di ogni test

ho scoperto che ero anche in grado di farla franca con la sola ricostruzione del database di test prima della prima prova in un test (o se un test istruisce esplicitamente a); prima che le altre prove, solo elimina tutti i dati per accelerare le cose un po '.

Ho letto blog Misko di Hevery sui test molto ultimamente. Esso copre questa situazione; avresti bisogno di usare DI (iniezione di dipendenza).

Mi sto lottando con questo un po 'così, e ho anche utilizzare Propel.

Per uno, si potrebbe spostare il metodo di "sospendere" per la classe "Oggetto", piuttosto che il peer. Per questa particolare funzione in ogni caso, non è necessario utilizzare i metodi statici per raggiungere questo obiettivo. Il tuo API potrebbe apparire come:

MyObjectPeer::retrieveByPK(1)->suspend();

Questo sarebbe verificabile tramite normali metodi di prova unità.

Se è davvero il database che deve essere testato, quindi per quanto ne so è necessario in realtà hanno il DB coinvolti nel test. Sto usando ltree e PostGIS molto nel mio progetto in corso e non riesco a pensare a nessun altro modo per eseguire unit test per la logica del modello che dipende dal DB diverso da quello di includerla nel mio test.

Questo è un esempio di una classe con dipendenza duro che non possono essere unità testabili.

Potremmo essere in grado di testare con una connessione a un altro database, ma poi, non una prova di unità è più, ma un test di integrazione.

La migliore alternativa che ci penso è quello di avere una classe QueryFactory che vi avvolgerà tutti i diversi metodi di cui avete bisogno e poi, si sarà in grado di prendere in giro esso.

In primo luogo nella prima creo un'interfaccia

interface iQueryFactory
{
    function firstFunction($argument);
    function secondFunction($argument, $argument2);
}

Il QueryFactory con tutta la vostra richiesta ORM abbiamo bisogno

class QueryFactory implements iQueryFactory
{
    function firstFunction($argument) 
    {
        // ORM thing
    }

    function secondFunction($argument, $argument2)
    {
        // ORM stuff
    }
}

C'è la logique affari con l'iniezione di fabbrica di query

class BusinessLogic 
{
    protected $queryFactory;

    function __construct($queryFactoryInjection) 
    {
        $this->queryFactory= $queryFactoryInjection;
    }

    function yourFunctionInYourBusinessLogique($argument, $argument2) 
    {
        // business logique

        try {
            $this->queryFactory->secondFunction($argument, $argument2);
        } catch (\Exception $e) {
            // log
            // return thing
        }

        // return stuff
    }
}

La parte finto, di notare che io non uso un quadro finto per il mio exemple (btw è possibile creare un setter risposta)

class QueryFactoryMock implements iQueryFactory
{
    function firstFunction($argument) 
    {
        if (is_null($argument)) 
        {
            throw new \Exception("");
        } 
        else 
        {
            return "succes";
        }
    }

    function firstFunction($argument, $argument2) 
    { 
        // sutff  
    }
}

Poi finalmente i test di unità che testano la nostra logica di business con l'implementazione mock

class BusinessLogicTest extends PHPUnit_Framework_TestCase 
{
    public function setUp() 
    {
        require_once "BusinessLogic.php";
    }

    public function testFirstFunction_WhenInsertGoodName() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject ->firstFunction("fabien");

        $this->assertEquals($response, "succes");
    }

    public function testFirstFunction_WhenInsetNull() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject->firstFunction(null);

        $this->assertEquals($response, "fail");
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top