2012-02-09 13 views
6

Estoy intentando escribir una prueba para un modelo que tenga tanto validadores normales como un validador personalizado utilizando un administrador de entidades y la solicitud. Estoy usando phpunit para mis pruebas si esto es importante por alguna razón.Symfony2 validación de pruebas unitarias con validador personalizado

Estoy probando el validador personalizado en otra prueba al anular tanto el administrador de entidades como la solicitud y luego validar algunos objetos. Como esto demuestra que la validación personalizada funciona, solo necesitaría probar la validación normal y, si esto es posible, simplemente dejar el validador personalizado.

Aquí es mi modelo:

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

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

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

    // ... 

} 

En mi prueba, me estoy poniendo el validador, la creación de un objeto y luego validarlo.

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

Por supuesto esto no funciona, ya que no puede encontrar el Validador definido para MyAssert \ Client, que es un servicio y debe ser resuelto por algún contenedor de inyección de dependencias.

¿Alguien tiene alguna idea de cómo codificar el validador personalizado o excluirlo de la validación?

+0

¿Por qué no probarlo en una prueba funcional? Ya está probando la unidad de su clase de validador personalizada, por lo que ahora todo lo que tiene que probar es en un entorno real. ¿Por qué no obtener el validador de un contenedor real, como el que se creó en un 'Symfony \ Bundle \ FrameworkBundle \ Test \ WebTestCase'? – Florian

+0

Bueno, primero que nada: las pruebas funcionales son lentas. Tengo que configurar la base de datos de prueba, rellenarla con accesorios y luego ejecutar la prueba. Esto es apto para cosas que solo se probarán con todo en su lugar, como el uso de una página web. Para probar una validación de modelo, no necesito una base de datos y todo, por lo que me gustaría simplemente probarla de forma aislada. – Sgoettschkes

+0

Acepto que es lento, pero con la carga diferida de DIC, solo se instanciaría el servicio 'validador' y sus dependencias directas (como el lector de anotaciones). Sin base de datos, sin llamadas http, nada más que llamar a '$ container-> get ('validator') -> validate ($ object);' – Florian

Respuesta

6

me gustaría ir con algo así:

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, lo intenté. Siguiente problema: el servicio tiene la solicitud de alcance porque el validador necesita la ip por razones de validación. Estoy pensando en cambiar la definición de validación de la anotación a yml y luego usar otro yml para sobrescribir este validador especial con un stub. – Sgoettschkes

+2

Puede cambiar manualmente el alcance del contenedor, usando '$ container-> enterScope ('request'); $ container-> set ('request', new Request, 'request'); ' – Florian

+0

Ahora está funcionando. Al sobreescribir la clase del validador personalizado con algún stub puedo probar bastante bien. ¡Gracias! – Sgoettschkes

3

Has probado esto?

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