6

I'm trying to write a test for an model which has both some normal validators and a custom validator using an entity manager and the request. I'm using phpunit for my tests if this matters for some reason.

I am testing the custom validator in another test by stubing both the entity manager and the request and then validating some objects. As this proves that the custom validation works, I would only need to test the normal validation and if this is possible simply leave the custom validator out.

Here is my Model:

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

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

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

    // ...

}

In my test, I'm getting the validator, creating an object and then validating it.

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

Of course this fails as it cannot find the Validator defined for MyAssert\Client, which is a service and needs to be resolved by some dependency injection container.

Anyone has any idea how to either stub the custom validator or to exclude it from validation?

3
  • Why not testing it in a functionnal test ? You already are unit testing your custom validator class, so now all you have to test is in a real environment. Why not getting the validator from a real container, like the one created in a Symfony\Bundle\FrameworkBundle\Test\WebTestCase ? Commented Feb 26, 2012 at 21:32
  • Well, first of all: functional tests are slow. I have to set up the test database, populate it with fixtures and then run the test. This is suiatable for stuff which is only to be tested with everything in place, like the usage of a webpage. For testing a model validation I don't need a database and everything, so I would like to just test it in isolation. Commented Feb 27, 2012 at 10:29
  • I agree it's slow, but with DIC lazy loading, you would only instanciate validator service and its direct dependencies (like annotation reader). No database, no http call, nothing else that calling $container->get('validator')->validate($object); Commented Feb 27, 2012 at 15:33

2 Answers 2

6
+100

I'd go with something like that:

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());
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Ok, I tried it. Next problem: The service has the scope request because the validator needs the ip for validation reasons. I'm thinking about changing the definition of validation from annotation to yml and then using another yml to overrite this special validator with a stub.
You can manually change the scope of the container, using $container->enterScope('request'); $container->set('request', new Request, 'request');
Now it's working. By overwriting the class of the custom validator with some stub I can test quite well. Thanks!
3

have you tried this?

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.