FunctionalTest Validator: Comparison with other property

149 views Asked by At

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;
}
1

There are 1 answers

0
Hans FooBar On BEST ANSWER

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

    }
}