Skip to content

Instantly share code, notes, and snippets.

@webdevilopers
Last active October 23, 2015 06:32
Show Gist options
  • Save webdevilopers/5f17b3e784a405f9bf1c to your computer and use it in GitHub Desktop.
Save webdevilopers/5f17b3e784a405f9bf1c to your computer and use it in GitHub Desktop.
Custom Validation, Callback and Constraints in Symfony2
framework:
validation: { enable_annotations: true }
framework:
test: ~
validation: { enable_annotations: true }
<?php
namespace KnpU\QADayBundle\Test;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Validator\Validation;
class EventTest extends KernelTestCase
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* {@inheritDoc}
*/
public function setUp()
{
self::bootKernel();
$this->entityManager = static::$kernel->getContainer()
->get('doctrine')
->getManager()
;
}
private function getKernel()
{
$kernel = $this->createKerel();
$kernel->boot();
return $kernel;
}
public function getValidator()
{
return Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
}
public function testFoo()
{
$event = new Event();
$errors = $this->getValidator()->validate($event);
$this->assertEquals(1, count($errors));
}
}
services:
unique_event_date_validator:
class: KnpU\QADayBundle\Validator\UniqueEventDateValidator
arguments:
- "@doctrine.orm.entity_manager"
tags:
-
name: validator.constraint_validator
alias: unique_event_date
@webdevilopers
Copy link
Author

Using PHPUnit 5.0.5 though my PHPStorm IDE says:
/usr/bin/php /tmp/ide-phpunit.php --configuration /var/www/foo/app/phpunit.xml PHPUnit 4.2.6

Based on this tutorial by @KnpLabs asked by @dextervip:

Works fine in PROD. But not with TEST env!

Throws:
Configuration read from /var/www/foo/app/phpunit.xml
PHP Fatal error: Class 'unique_event_date' not found in /var/www/foo/vendor/symfony/symfony/src/Symfony/Component/Validator/ConstraintValidatorFactory.php on line 46

Twitter discussion:

@webdevilopers
Copy link
Author

Possibly related to:

I removed the validateBy method and now I get:
PHPUnit_Framework_Error : Argument 1 passed to UniqueEventDateValidator::__construct() must be an instance of Doctrine\ORM\EntityManager

/** @Annotation */
class UniqueEventDateValidator extends ConstraintValidator
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

@webdevilopers
Copy link
Author

Looks like this is an autoloading problem with Unit Tests and the Symfony Bootstrap?

I'm using the /var/www/foo/vendor/autoload.php Autoloader and phpunit.xml.

<?xml version="1.0" encoding="UTF-8"?>

<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="bootstrap.php.cache"
>
    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>../src/*/*Bundle/Tests</directory>
            <directory>../src/*/Bundle/*Bundle/Tests</directory>
        </testsuite>
    </testsuites>

    <!--
    <php>
        <server name="KERNEL_DIR" value="/path/to/your/app/" />
    </php>
    -->

    <filter>
        <whitelist>
            <directory>../src</directory>
            <exclude>
                <directory>../src/*/*Bundle/Resources</directory>
                <directory>../src/*/*Bundle/Tests</directory>
                <directory>../src/*/Bundle/*Bundle/Resources</directory>
                <directory>../src/*/Bundle/*Bundle/Tests</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

Possibly related issues:

@webdevilopers
Copy link
Author

Updated Composer to use current PHPUnit 5.0.*:

    "phpunit/phpunit": "5.0.*",
    "phpunit/php-code-coverage": "dev-master#b8436b000263f6d72fbad1d36890e247ce84857e"

Same error!

@webdevilopers
Copy link
Author

The following solution worked for me:

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class EventControllerTest extends KernelTestCase
{
    /**
     * {@inheritDoc}
     */
    public function setUp()
    {
        self::bootKernel();

        $this->validator = static::$kernel->getContainer()->get('validator');
    }
}

Getting the validator directly from the container.

See symfony/symfony#12931 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment