2012-02-09 13 views
6

Sto provando a scrivere un test per un modello che ha sia alcuni validatori normali che un validatore personalizzato utilizzando un gestore di entità e la richiesta. Sto usando phpunit per i miei test se questo è importante per qualche motivo.symfony2 convalida dell'unità test con validatore personalizzato

Sto testando il validatore personalizzato in un altro test bloccando sia il gestore entità che la richiesta e quindi convalidando alcuni oggetti. Poiché ciò dimostra che la convalida personalizzata funziona, avrei solo bisogno di testare la normale validazione e se è possibile semplicemente lasciare fuori il validatore personalizzato.

Ecco il mio modello:

/** 
* @MyAssert\Client() 
*/ 
abstract class BaseRequestModel { 

    /** 
    * @Assert\NotBlank(message="2101") 
    */ 
    protected $clientId; 

    /** 
    * @Assert\NotBlank(message="2101") 
    */ 
    protected $apiKey; 

    // ... 

} 

Nella mia prova, sto diventando il validatore, creando un oggetto e poi convalidarlo.

$validator = ValidatorFactory::buildDefault()->getValidator(); 
$requestModel = new RequestModel(); 
$errors = $validator->validate($requestModel); 

Naturalmente questo viene a mancare in quanto non riesce a trovare il Validator definito per MyAssert \ Client, che è un servizio e deve essere risolto da alcuni container iniezione di dipendenza.

Qualcuno ha idea di come sia stub il validatore personalizzato o per escluderlo dal convalida?

+0

Perché non testarlo in un test funzionale? Stai già testando la tua classe di validatori personalizzati, quindi ora tutto ciò che devi testare è in un ambiente reale. Perché non ottenere il validatore da un contenitore reale, come quello creato in un 'Symfony \ Bundle \ FrameworkBundle \ Test \ WebTestCase'? – Florian

+0

Bene, prima di tutto: i test funzionali sono lenti. Devo impostare il database di test, popolarlo con fixture e quindi eseguire il test. Questo è fattibile per cose che devono essere testate solo con tutto, come l'uso di una pagina web. Per testare una validazione del modello non ho bisogno di un database e di tutto, quindi mi piacerebbe testarlo da solo. – Sgoettschkes

+0

Concordo sul fatto che sia lento, ma con il caricamento pigro della DIC, si dovrebbe solo instanciare il servizio 'validator' e le sue dipendenze dirette (come il lettore di annotazioni). Nessun database, nessuna chiamata http, nient'altro che chiama '$ container-> get ('validator') -> validate ($ object);' – Florian

risposta

6

mi piacerebbe andare con qualcosa di simile:

class MyTest extends Symfony\Bundle\FrameworkBundle\Test\WebTestCase 
{ 
    private function getKernel() 
    { 
     $kernel = $this->createKernel(); 
     $kernel->boot(); 

     return $kernel; 
    } 

    public function testCustomValidator() 
    { 
     $kernel = $this->getKernel(); 
     $validator = $kernel->getContainer()->get('validator'); 

     $violationList = $validator->validate(new RequestModel); 

     $this->assertEquals(1, $violationList->count()); 
     // or any other like: 
     $this->assertEquals('client not valid', $violationList[0]->getMessage()); 
    } 
} 
+0

Ok, l'ho provato. Prossimo problema: il servizio ha la richiesta di ambito perché il validatore ha bisogno dell'ip per ragioni di validazione. Sto pensando di cambiare la definizione di convalida dall'annotazione in yml e quindi di usare un altro yml per sovrascrivere questo validatore speciale con uno stub. – Sgoettschkes

+2

È possibile modificare manualmente l'ambito del contenitore, usando '$ container-> enterScope ('richiesta'); $ container-> set ('request', new Request, 'request'); ' – Florian

+0

Ora funziona. Sovrascrivendo la classe del validatore personalizzato con qualche stub posso testare abbastanza bene. Grazie! – Sgoettschkes

3

Hai provato questo?

$validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator(); 
Problemi correlati