Symfony2: Testing entity validation constraints

Viewed 27207

Does anyone have a good way to unit test an entity's validation constraints in Symfony2?

Ideally I want to have access to the Dependency Injection Container within the unit test which would then give me access to the validator service. Once I have the validator service I can run it manually:

$errors = $validator->validate($entity);

I could extend WebTestCase and then create a client to get to the container as per the docs however it doesn't feel right. The WebTestCase and client read in the docs as more of a facility to test actions as a whole and therefore it feels broken to use it to unit test an entity.

So, does anyone know how to either a) get the container or b) create the validator inside a unit test?

7 Answers

Answer (b): Create the Validator inside the Unit Test (Symfony 2.0)

If you built a Constraint and a ConstraintValidator you don't need any DI container at all.

Say for example you want to test the Type constraint from Symfony and it's TypeValidator. You can simply do the following:

use Symfony\Component\Validator\Constraints\TypeValidator;
use Symfony\Component\Validator\Constraints\Type;

class TypeValidatorTest extends \PHPUnit_Framework_TestCase
{
  function testIsValid()
  {
    // The Validator class.
    $v = new TypeValidator();

    // Call the isValid() method directly and pass a 
    // configured Type Constraint object (options
    // are passed in an associative array).

    $this->assertTrue($v->isValid(5, new Type(array('type' => 'integer'))));
    $this->assertFalse($v->isValid(5, new Type(array('type' => 'string'))));
  }
}

With this you can check every validator you like with any constraint configuration. You neither need the ValidatorFactory nor the Symfony kernel.

Update: As @psylosss pointed out, this doesn't work in Symfony 2.5. Nor does it work in Symfony >= 2.1. The interface from ConstraintValidator got changed: isValid was renamed to validate and doesn't return a boolean anymore. Now you need an ExecutionContextInterface to initialize a ConstraintValidator which itself needs at least a GlobalExecutionContextInterface and a TranslatorInterface... So basically it's not possible anymore without way too much work.

Related