symfonysymfony-validator

FunctionalTest Validator: Comparison with other property


based on the example LessThan.html#propertypath I would like to write a FunctionalTest for my own validator @Assert\Amount. $amount is to be validated depending on $currency.

My question is, how can I set the value for $currency in the FunctionalTest for the Amount Validator? I have looked at the tests of the package symfony/validator but can't find a clue. I have already written FunctionalTests for validators. But I am not getting anywhere with this requirement.

Could someone give me a hint or show me an example.

Example:

class Entity
{
     /**
     * @var \string
     * @Assert\Currency()
     */
    protected $currency;

     /**
     * @var \float
     * @Assert\Amount(propertyPath="currency")
     */
    protected $amount;
}

Solution

  • I have found a solution. I validated the complete entity and looked at the object in the validator and found the complete entity.

    When I thought about how to test it, I did some research and found other tests that did the same. I don't know if this is the best solution, but I can now write my tests.

    ConstraintValidatorTestCase

    <?php
        
    namespace App\Tests\Validator\Constraint;
    
    use App\Entity\Entity;
    use App\Validator\MinimumAmount;
    use App\Validator\MinimumAmountValidator;
    use Symfony\Component\Validator\Context\ExecutionContext;
    use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
    use Symfony\Component\Validator\Validator\ValidatorInterface;
    use Symfony\Contracts\Translation\TranslatorInterface;
    use Symfony\Component\Validator\Context\ExecutionContextInterface;
    use Symfony\Component\Validator\ConstraintValidatorInterface;
    
    class MinimumAmountValidatorTest extends ConstraintValidatorTestCase
    {
       /**
       * @var ExecutionContextInterface
       */
       protected $context;
    
        /**
        * @var ConstraintValidatorInterface
        */
        protected $validator;
    
        /**
        * @var Constraint
        */
        protected $constraint;
    
        protected function setUp(): void
        {
            $this->constraint = new Entity();
            $this->context = $this->createContext();
            $this->validator = $this->createValidator();
            $this->validator->initialize($this->context);
        }
    
        public function createValidator(): MinimumAmountValidator
        {
            return new MinimumAmountValidator();
        }
    
        public function createContext(): ExecutionContext
        {
            $myEntity = new Entity();
            $myEntity->setCurrency('EUR');
    
            $translator = $this->createMock(TranslatorInterface::class);
            $translator->expects($this->any())->method('trans')->willReturnArgument(0);
            $validator = $this->createMock(ValidatorInterface::class);
    
            $executionContext = new ExecutionContext($validator, $myEntity, $translator);
            $context->setNode('InvalidValue', null, null, 'property.path');
            $context->setConstraint($this->constraint);
            return $executionContext;
        }
    
    
        public function testValidation()
        {
            $this->validator->validate(40.00, new  MinimumAmount());
            $this->assertNoViolation();
        }
    }
     
    

    Constraint

    <?php
    
    namespace App\Validator;
    
    use Symfony\Component\Validator\Constraint;
    
    /**
     * @Annotation
     */
    class MinimumAmount extends Constraint
    {
        /**
         * @var string
         */
        public $message = '';
    
        /**
         * @return string
         */
        public function validatedBy(): string
        {
            return MinimumAmountValidator::class;
        }
    }
    

    Validator

    <?php
    
    namespace App\Validator;
    
    use App\Entity\Entity;
    use Symfony\Component\Validator\Constraint;
    use Symfony\Component\Validator\ConstraintValidator;
    
    class MinimumAmountValidator extends ConstraintValidator
    {
        /**
         * @param float $value
         * @param Constraint $constraint
         *
         * @return void
         */
        public function validate($value, Constraint $constraint)
        {
            /**
             * @var Entity
             */
            $contextRoot = $this->context->getRoot();
            $currency = $contextRoot->getCurrency(); // EUR
            $amount = $value; // 40.00
    
            // Validation implementation
    
        }
    }