0

我想测试 Symfony2 的表单类型。我有一个自定义表单类型,我的测试如下所示:

/**
 * @param  \Acme\UserBundle\Entity\User $user
 */
function let(\Acme\UserBundle\Entity\User $user)
{
    $this->beConstructedWith($user);
}

function it_is_initializable()
{
    $this->shouldHaveType('Acme\UserBundle\Form\Type\RegistrationFormType');
}

/**
 * @param \Symfony\Component\Form\FormBuilderInterface $builder
 */
function it_builds_form(\Symfony\Component\Form\FormBuilderInterface $builder)
{
    $this->buildForm($builder, []);
}

我得到: 致命错误:在非对象上调用成员函数 add() 在 buildForm 方法中我从 FormBuilderInterface 调用 $this->add 方法我该如何解决这个问题?

4

1 回答 1

4

您没有发布表单代码,但我怀疑问题在于构建器的 add() 方法使用的流畅界面。如果您像这样多次调用 add() :

$builder
    ->add('username')
    ->add('email')
    ->add(...)
    ->add(...)
    ->add('save', 'submit');

然后问题将出现在第一个 add() 之后,因为它没有返回对象(因此出现“在非对象上调用成员函数 add()”错误消息)。

如果您使用的是 fluent 样式,则需要“训练” $builder 协作者,以便 phpspec/mockery 可以为连续调用 add() 返回相同的构建器对象:

$builder->add(Argument::any(), Argument::any())->willReturn($builder);
$this->buildForm($builder, []);

我认为 Symfony 2 表单可能不是 phpspec 测试的最佳候选者,因为您真的只想测试您的类的公共 API,而不是测试您不拥有的代码(即框架/3rd-party 库) .

您正在测试的表单类型不是实际生成的表单,它更像是在需要时用于构建表单的“蓝图”,因此我认为更难测试表单是否具有某些字段或选项,等等,因为这不是由您的代码调用的,它会在表单框架处理表单类型时自动发生。

创建真实表单的工作发生在构建器内部,在此表单类型规范的上下文中,构建器是协作者而不是真正的构建器对象(也不是您要测试的代码)。

于 2014-07-03T01:15:28.973 回答