我如何进行单元测试 ContainsItalianVatinValidator
自定义验证器,但无需访问容器* 和 validator
服务(因此,创建一个 stub 对象)?
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
// ...
}
}
在我的测试用例中,我知道我应该访问
ConstraintViolationList
,但我不知道如何从验证器本身做到这一点: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());
}
}
最佳答案
当你查看验证器的父类时Symfony\Component\Validator\ConstraintValidator
你看到有一个方法叫 initialize
它采用 Symfony\Component\Validator\ExecutionContext
的实例作为论据。
创建验证器后,您可以调用 initialize
方法并将模拟上下文传递给验证器。您不必测试 addViolation
方法工作正常,您只需要测试它是否被调用以及是否使用正确的参数调用。您可以使用 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);
...
在此代码中,您必须将 [message] 替换为存储在
$constraint->message
中的消息。 .实际上,这个问题与 PHPUnit 相关而不是与 Symfony 相关。您可能会找到 Test Doubles PHPUnit 文档的章节很有趣。
关于symfony - 在 Symfony 2.1 中单元测试自定义验证约束但不访问容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12397011/