3

我正在尝试测试自定义表单类型的绑定事件的方法。

这是代码

public function bind(DataEvent $event)
{
    $form = $event->getForm();

    if($form->getNormData() instanceof BaseFileInterface && !$event->getData() instanceof UploadedFile) {
        $event->setData($form->getNormData());
    }

    if($event->getData() instanceof UploadedFile) {
        $hander = $this->handlerManager->getHandler(
            $form->getParent()->getConfig()->getDataClass(), 
            $form->getName()
        );

        $datas = $hander->createBaseFile($event->getData());
        $event->setData($datas);
    }

    if(is_string($event->getData())) {
        $event->setData(null);
    }
}

和类型的表单生成器:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->addEventSubscriber(new BaseFileListener($this->handlerManager))
        ->addViewTransformer(new BaseFileToStringTransformer())
    ;
}

我的测试类继承自 Symfony\Component\Form\Tests\FormIntegrationTestCase 并且正在这样做:

protected function setUp()
{
    parent::setUp();

    $this->handlerManager = $this->getHandlerManagerMock();

    $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
    $this->builder = new FormBuilder(null, null, $this->dispatcher, $this->factory);

    $this->form =  $this->factory->create('my_file');
    $this->form->setParent($this->getFormMock())->setData(new DummyEntity());
}

protected function getFormMock()
{

    $mock = $this
        ->getMockBuilder('Symfony\Component\Form\Tests\FormInterface')
        ->disableOriginalConstructor()
        ->getMock()
    ;

    return $mock;
}

public function testBindHandleNewFileWithNonEmptyField()
{
    $data = $file = new UploadedFile(
        __DIR__.'/../Fixtures/test.gif',
        'original.gif',
        'image/gif',
        filesize(__DIR__.'/../Fixtures/test.gif'),
        null
    );

    $event = new FormEvent($this->form, $data);

    $listener = new BaseFileListener($this->handlerManager);
    $listener->bind($event);

    $this->assertInstanceOf('My\FooBundle\Entity\BaseFileInterface', $event->getData());
    $this->assertNotEquals($event->getData(), $this->form->getNormData());
}

问题是 $form->getParent()->getConfig()->getDataClass() 在 getDataClass() 上抛出异常。

问题是如何正确构建表单以执行绑定测试?

4

1 回答 1

3

好的,回答我自己:)

这是 phpunit 中很好的模拟:

protected function setUp()
{
    parent::setUp();

    $this->handlerManager = $this->getHandlerManagerMock();

    $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
    $this->builder = new FormBuilder(null, null, $this->dispatcher, $this->factory);

    $this->form =  $this->factory->create('my_file');
    $this->form->setParent($this->getFormMock());
}

protected function getFormMock()
{
    $mock = $this->getMock('Symfony\Component\Form\Tests\FormInterface');

    $mock
        ->expects($this->any())
        ->method('getConfig')
        ->will($this->returnValue($this->getFormConfigMock()))
    ;

    return $mock;
}

protected function getFormConfigMock()
{
    $mock = $this->getMockBuilder('Symfony\Component\Form\FormConfigInterface')
        ->disableOriginalConstructor()
        ->getMock();

    $mock
        ->expects($this->any())
        ->method('getDataClass')
        ->will($this->returnValue('My\FooBundle\Tests\DummyEntity'))
    ;

    return $mock;
}

我以为我可以在不使用 mock 的情况下重建整个表单,但这似乎是不可能的。

如果有人有更好的解决方案,我很感兴趣。

于 2012-10-23T17:24:17.650 回答