2

を拡張するクラスをテストしようとしていSymfony\Component\Form\AbstractTypeますが、必要なbuildFormメソッドを PHPUnit モック オブジェクトでテストするのに問題があります。

class PageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', 'text');
    }

    // ...
 }

テストコードの例を次に示します。

public function testBuildForm()
{
    $form = new PageType($this->manager);
    $formBuilder = $this->getMock('Symfony\Component\Form\FormBuilderInterface');
    $form->buildForm($formBuilder, array());
}

残念ながら、への呼び出しはgetMock()失敗します:

PHP Fatal error:  Class Mock_FormBuilderInterface_f36f83d4 must implement interface Traversable as part of either Iterator or IteratorAggregate in Unknown on line 0

このバグに引っかかったのではないかと思います: https://github.com/sebastianbergmann/phpunit/issues/604

そこで、この問題を回避するためのインターフェイスを作成しました。

use Symfony\Component\Form\FormBuilderInterface;

interface FormBuilderInterfaceExtender extends \Iterator, FormBuilderInterface
{
}

テストコードを変更しました:

public function testBuildForm()
{
    $form = new PageType($this->manager);
    $formBuilder = $this->getMock('Pwn\ContentBundle\Tests\Helper\FormBuilderInterfaceExtender');
    $form->buildForm($formBuilder, array());
}

Symfony\Component\Form\FormBuilderInterface今、私はFormBuilderインスタンスを持っていますが、PHP はそれを のインスタンスとして認識していません$form->buildForm()

Argument 1 passed to Pwn\ContentBundle\Form\Type\PageType::buildForm() must be an instance of Symfony\Component\Form\FormBuilderInterface, instance of Mock_FormBuilderInterfaceExtender_3527f313 given

モックオブジェクトを使用した他のケースでは、ヒンティングを入力しinstanceofて正しく動作しますが、ここではそうではありません:

var_dump($formBuilder);
var_dump($formBuilder instanceof \Symfony\Component\Form\FormBuilderInterface);

与える

class Mock_FormBuilderInterfaceExtender_76df04af#19 (1) {
  private $__phpunit_invocationMocker =>
  NULL
}
bool(false)

インターフェイスを実装するクラスをモックすることで、これを機能させることができるようです。

$formBuilder = $this->getMockBuilder('Symfony\Component\Form\FormBuilder')
                    ->disableOriginalConstructor()
                    ->getMock();

var_dump($formBuilder instanceof \Symfony\Component\Form\FormBuilderInterface);
// ^ gives bool(true)

ただし、インターフェイス自体を使用できるようにする必要がありますか? インターフェイスを拡張すると型ヒントが「失われる」のはなぜですか?

4

2 に答える 2

2

Symfony2インターフェースをテストできないときはいつでも、コンポーネントのTestsディレクトリを調べて、テスト専用のモックがあるかどうかを確認してください。テストインターフェイスは実際のインターフェイスを拡張し、phpunitで実行するために必要な微調整を追加します。

Symfony\Component\Form\Tests\FormBuilderInterfaceあなたの場合は、代わりにモックを試してください。

于 2013-01-05T18:57:05.210 に答える
1

PHPUnitはインターフェースをうまくモックできるようで、他のインターフェースを拡張するインターフェースには問題はありません。このクラスとテストケースを見てください

NamespaceA.php

<?php
namespace Testing;
interface NamespaceA {}

TestMockInterfaces.php

<?php
require 'NamespaceA.php';

interface Custom extends Testing\NamespaceA, Iterator, ArrayAccess {}

class TestMockInterfaces extends PHPUnit_Framework_TestCase
{
    public function testMocks()
    {
        $oSolidMock = $this->getMock('Iterator');
        $this->assertTrue($oSolidMock instanceof Iterator);

        $oSketchyMock = $this->getMock('Custom');
        $this->assertTrue($oSketchyMock instanceof Iterator);
        $this->assertTrue($oSketchyMock instanceof ArrayAccess);
        $this->assertTrue($oSketchyMock instanceof \Testing\NamespaceA);
    }
}

これは100%を通過するので、何か他のことが起こっているのではないかと思います。

モックした後、それがあなたが期待するものであるかどうかFormBuilderInterfaceExtender試してみてください。var_dump(class_implements($formBuilder));

于 2013-01-04T18:04:14.403 に答える