How can i unit test ContainsItalianVatinValidator
custom validator, but w*ithout accessing the container* and the validator
service (and thus, create a stub object)?
class ContainsItalianVatinValidator extends ConstraintValidator
{
/**
* @param mixed $value
* @param \Symfony\Component\Validator\Constraint $constraint
*/
public function validate($value, Constraint $constraint)
{
if (!preg_match('/^[0-9]{11}$/', $value, $matches)) {
$this->context->addViolation($constraint->message, array(
'%string%' => $value
));
}
// Compute and check control code
// ...
}
}
In my test case i know i should access the ConstraintViolationList
, but i don't know how to do it from the validator itself:
class ContainsItalianVatinValidatorTest extends \PHPUnit_Framework_TestCase
{
public function testEmptyItalianVatin()
{
$emptyVatin = '';
$validator = new ContainsItalianVatinValidator();
$constraint = new ContainsItalianVatinConstraint();
// Do the validation
$validator->validate($emptyVatin, $constraint);
// How can a get a violation list and call ->count()?
$violations = /* ... */;
// Assert
$this->assertGreaterThan(0, $violations->count());
}
}
When you take a look at the parent class of the validator Symfony\Component\Validator\ConstraintValidator
you see that there is a method called initialize
which takes an instance of Symfony\Component\Validator\ExecutionContext
as argument.
After you created the validator you can call the initialize
method and pass a mock context to the validator. You don't have to test if the addViolation
method works correctly, you only have to test if it is called and if it is called with the correct parameters. You can do that with the mock functionality of PHPUnit.
...
$validator = new ContainsItalianVatinValidator();
$context = $this->getMockBuilder('Symfony\Component\Validator\ExecutionContext')-> disableOriginalConstructor()->getMock();
$context->expects($this->once())
->method('addViolation')
->with($this->equalTo('[message]'), $this->equalTo(array('%string%', '')));
$validator->initialize($context);
$validator->validate($emptyVatin, $constraint);
...
In this code you have to replace [message] with the message stored in $constraint->message
.
Actually, this question is more related to PHPUnit than to Symfony. You may find the Test Doubles chapter of the PHPUnit documentation interesting.