Php 带约束的Symfony2单元测试表单
我有一个表单,它没有连接到实体,但有如下所述的约束: ContactBundle\Tests\Form\Type\TestedTypeTest::testSubmitValidData Symfony\Component\OptionsResolver\Exception\InvalidOptionsException:选项“约束”不存在。已知选项有:“操作”、“属性”、“自动初始化”、“块名称”、“按引用”、“复合”、“数据”、“数据类”、“禁用”、“空数据”、“错误冒泡”、“继承数据”、“标签”、“标签属性”、“映射”、“最大长度”、“方法”、“模式”、“发布最大大小消息”、“属性路径”、“只读”、“必需”、“翻译域”、“修剪”,“虚拟的” 以下是表格的一部分:Php 带约束的Symfony2单元测试表单,php,forms,unit-testing,symfony,Php,Forms,Unit Testing,Symfony,我有一个表单,它没有连接到实体,但有如下所述的约束: ContactBundle\Tests\Form\Type\TestedTypeTest::testSubmitValidData Symfony\Component\OptionsResolver\Exception\InvalidOptionsException:选项“约束”不存在。已知选项有:“操作”、“属性”、“自动初始化”、“块名称”、“按引用”、“复合”、“数据”、“数据类”、“禁用”、“空数据”、“错误冒泡”、“继承数据”、“标
class ContactType extends AbstractType
{
/**
* Build the form
* @param \Symfony\Component\Form\FormBuilderInterface $builder BuilderInterface
* @param array $aOption Array of options
*/
public function buildForm(FormBuilderInterface $builder, array $aOption)
{
///..
$builder->add('name', 'text', array(
'constraints' => array(
new NotBlank(),
new Length(array('min' => 3)),
),
))
->add('address', 'textarea', array(
'required' => false
))
//..
;
//..
这是单元测试
class TestedTypeTest extends TypeTestCase
{
public function testSubmitValidData()
{
$formData = array(
'name' => 'Test Name',
'address' => '',
);
$type = new ContactType();
$form = $this->factory->create($type, $formData);
$form->submit($formData);
$this->assertTrue($form->isSynchronized());
$view = $form->createView();
$children = $view->children;
foreach (array_keys($formData) as $key) {
$this->assertArrayHasKey($key, $children);
}
}
}
我猜这是测试而不是表单的问题,因为表单按预期工作。我不确定应该更改什么。
任何帮助或建议都很方便
谢谢我认为问题在于您还将formData传递给工厂的create方法
只需通过$form->submit($formData)
传递表单数据就可以了,就像您已经在代码中一样
更多文档:
编辑:
看起来您必须在测试设置中将验证程序/约束扩展添加到factory对象中,如此处所述是的,Rob是对的,我需要添加验证程序/约束扩展。如下图所示:
class TestedTypeTest extends TypeTestCase
{
protected function setUp()
{
parent::setUp();
$validator = $this->getMock('\Symfony\Component\Validator\Validator\ValidatorInterface');
$validator->method('validate')->will($this->returnValue(new ConstraintViolationList()));
$formTypeExtension = new FormTypeValidatorExtension($validator);
$coreExtension = new CoreExtension();
$this->factory = Forms::createFormFactoryBuilder()
->addExtensions($this->getExtensions())
->addExtension($coreExtension)
->addTypeExtension($formTypeExtension)
->getFormFactory();
}
//..
我建议您重写TypeTestCase::getExtensions()方法 在测试类中添加createValidator()方法:
protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array())
{
$translator = new IdentityTranslator();
$translator->setLocale('en');
$contextFactory = new ExecutionContextFactory($translator);
$validatorFactory = new ConstraintValidatorFactory();
return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $objectInitializers);
}
无需重写TypeTestCase::getTypeExtensions(),因为ValidatorExtension类已具有loadTypeExtensions()方法
然后,您的测试方法可以如下所示:
public function testSubmitValidData()
{
$formData = array(
'name' => 'Test Name',
'address' => '',
);
$form = $this->factory->create(ContactType::class);
$form->submit($formData);
$this->assertTrue($form->isValid());
$this->assertTrue($form->isSynchronized());
$view = $form->createView();
$children = $view->children;
foreach (array_keys($formData) as $key) {
$this->assertArrayHasKey($key, $children);
}
}
您可以测试无效数据:
public function testSubmitInvalidValidData()
{
$formData = array(
'name' => 'T',
);
$form = $this->factory->create(ContactType::class);
$form->submit($formData);
$this->assertFalse($form->isValid());
$this->assertFalse($view->children['name']->vars['valid']);
}
资料来源:
ValidatorExtensionTrait
添加到运行测试的类中
use Symfony\Component\Form\Test\TypeTestCase;
class TestedTypeTest extends TypeTestCase
{
use \Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait;
public function testSubmitValidData()
{
$formData = [...];
$type = new ContactType();
$form = $this->factory->create($type, $formData);
}
}
trait负责添加使“constraints”选项可用所需的扩展。是的,我尝试过:$type=new ContactType();$form=$this->factory->create($type);但它仍然是同一个问题。根据文档,create的第二个参数可以是对象、数组或无。公共函数create($type='form',$data=null,array$options=array());FormFactoryInterface的Api文档:哪一行导致执行选项?(以及create()的其他参数最终作为FormType的构建表单中的第二个参数传递(FormBuilderInterface$builder,array$AOOPTION))从堆栈跟踪:symfony/symfony/src/symfony/Component/OptionsResolver/OptionsResolver.php:255 symfony/symfony/src/symfony/Component/OptionsResolver/OptionsResolver/OptionsResolver.php:219 symfony/symfony/symfony/src/symfony/Component/Form/resolver.php:109 symfony/symfony/symfony/src/symfony/symfony/Component/Formm/FormBuilder.php:106 symfony/symfony/src/symfony/Component/Form/FormBuilder.php:268 symfony/symfony/src/symfony/Component/FormBuilder.php:216 symfony/symfony/src/symfony/Component/Form/FormFactory.php:39/Tests/Form/Type/ContactTypeTest.php:34:$Form=$this->->->->->->-create($Type);我更新了我的答案…您必须添加一些设置内容以获得测试框架支持的约束…这不只是剔除约束吗?因此很难测试提交的数据是否通过约束?事实上,看起来Victor s是正确的。我允许您完成测试,但它不会测试约束。我创建了一个输入无效的testSubmitInvalidData方法,但是$form->isValid()将始终返回true。关闭,但没有雪茄。您的ConstraintViolationList为空,您的表单始终有效
use Symfony\Component\Form\Test\TypeTestCase;
class TestedTypeTest extends TypeTestCase
{
use \Symfony\Component\Form\Test\Traits\ValidatorExtensionTrait;
public function testSubmitValidData()
{
$formData = [...];
$type = new ContactType();
$form = $this->factory->create($type, $formData);
}
}