【问题标题】:Unit testing Symfony callback单元测试 Symfony 回调
【发布时间】:2017-03-19 02:41:48
【问题描述】:

您好,在联合测试 Symfony 2.8 回调方面需要一些帮助。 我认为我没有正确设置它,因为当我知道它应该失败时测试通过了

实体设置:

Contact 实体中的验证回调:

 /**
 * Validation callback for contact
 * @param \AppBundle\Entity\Contact $object
 * @param ExecutionContextInterface $context
 */
public static function validate(Contact $object, ExecutionContextInterface $context)
{
    /**
     * Check if the country code is valid
     */
    if ($object->isValidCountryCode() === false) {
        $context->buildViolation('Cannot register in that country')
                ->atPath('country')
                ->addViolation();
    }
}

Contact实体中的方法isValidCountryCode:

/**
 * Get a list of invalid country codes
 * @return array Collection of invalid country codes
 */
public function getInvalidCountryCodes()
{
    return array('IS');
}

检查国家代码是否无效的方法:

/**
 * Check if the country code is valid
 * @return boolean
 */
public function isValidCountryCode()
{
    $invalidCountryCodes = $this->getInvalidCountryCodes();
    if (in_array($this->getCountry()->getCode(), $invalidCountryCodes)) {
        return false;
    }
    return true;
}

validation.yml

AppBundle\Entity\Contact:
properties:
    //...

    country:
        //..
        - Callback: 
            callback: [ AppBundle\Entity\Contact, validate ]
            groups: [ "AppBundle" ]

测试类:

//..
use Symfony\Component\Validator\Validation;

class CountryTest extends WebTestCase
{
  //...

public function testValidate()
{
    $country = new Country();
    $country->setCode('IS');

    $contact = new Contact();
    $contact->setCountry($country);

    $validator = Validation::createValidatorBuilder()->getValidator();

    $errors = $validator->validate($contact);

    $this->assertEquals(1, count($errors));
}

此测试返回 $errors,计数为 0,但应为 1,因为国家代码“IS”无效。

【问题讨论】:

    标签: validation unit-testing symfony callback phpunit


    【解决方案1】:

    第一个问题是关于yml文件中约束的定义:你需要把callback放在constraint下面而不是properties,所以修改validation.yml文件如下:

    validation.yml

    AppBundle\Entity\Contact:
        constraints:
           - Callback:
                callback: [ AppBundle\Entity\Contact, validate ]
                groups: [ "AppBundle" ]
    

    第二个在 testCase 中:你需要从容器中获取验证器服务,而不是使用构建器创建一个新服务:这个对象没有使用对象结构等初始化。

    第三回调约束仅针对AppBundle验证组定义,因此将验证组传递给验证器服务(作为服务的第三个参数)。

    所以改变 testClass 如下:

        public function testValidate()
        {
            $country = new Country();
            $country->setCode('IS');
    
            $contact = new Contact();
            $contact->setCountry($country);
    
    //        $validator = Validation::createValidatorBuilder()->getValidator();
            $validator = $this->createClient()->getContainer()->get('validator');
    
            $errors = $validator->validate($contact, null, ['AppBundle']);
            $this->assertEquals(1, count($errors));
        }
    

    然后测试用例变成了绿色。

    希望有帮助

    【讨论】:

    • 遗憾的是这也不起作用。将组作为第二个参数传递将返回弃用警告: ` 自 2.5 版以来不推荐使用 Valid 约束的“deep”选项,并将在 3.0 中删除。遍历数组时,总是遍历嵌套数组。遍历嵌套对象时,使用它们的遍历策略: Symfony\Component\Validator\ValidatorInterface::validate 方法在 2.5 版中已弃用,并将在 3.0 版中删除。改用 Symfony\Component\Validator\Validator\ValidatorInterface::validate 方法`
    猜你喜欢
    • 2017-05-09
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多