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