php - Symfony FormType 测试处理 EntityType

标签 php forms unit-testing symfony

我对 Symfony FormType 测试有疑问。 http://symfony.com/doc/current/cookbook/form/unit_testing.html

在我的表单类型中,entity 类型很常见。使用学说实体表单类型测试表单类型是可怕的。

这是我的表单域。

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('products', 'entity', array(
        'class'     => 'AcmeDemoBundle:Product',
        'label'     => 'Product',
        'property'  => 'name',
        'required'  => false,
        'mapped'    => true,
        'multiple'  => true,
        'expanded'  => true
    ));
}

这是该领域的模拟。

private function getEntityTypeMock()
{
    $entityRepositoryMock = $this->getMockBuilder('Doctrine\ORM\EntityRepository')
        ->disableOriginalConstructor()
        ->getMock()
    ;

    $entityRepositoryMock->expects($this->once())
        ->method('findAll')
        ->will($this->returnValue(array()));

    $classMetaDataMock = $this->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadata')
        ->disableOriginalConstructor()
        ->getMock();

    $mockEntityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager')
        ->disableOriginalConstructor()
        ->getMock();

    $mockEntityManager->expects($this->any())
        ->method('getClassMetadata')
        ->will($this->returnValue($classMetaDataMock));

    $mockEntityManager->expects($this->once())
        ->method('getRepository')
        ->will($this->returnValue($entityRepositoryMock));

    $mockRegistry = $this->getMockBuilder('Doctrine\Bundle\DoctrineBundle\Registry')
        ->disableOriginalConstructor()
        ->getMock();

    $mockRegistry->expects($this->any())
        ->method('getManagerForClass')
        ->will($this->returnValue($mockEntityManager));

    $mockEntityType = $this->getMockBuilder('Symfony\Bridge\Doctrine\Form\Type\EntityType')
        ->setMethods(array('getName'))
        ->setConstructorArgs(array($mockRegistry))
        ->getMock();

    $mockEntityType->expects($this->any())->method('getName')
        ->will($this->returnValue('entity'));

    return $mockEntityType;
}

这真的是正确的方法吗?在 TypeTestCase 中,我无权访问任何内容,没有容器,没有内核,什么都没有。这使得测试表单类型变得非常困难和令人沮丧。

有没有更好的方法来测试表单类型?或者更简单的方法来处理具有 ORM 依赖性的类型?

干杯。

最佳答案

我在对非常依赖服务容器的东西进行单元测试时遇到了困难。起初我试着像你一样 mock 一切。这可以使单元测试通过很大的努力(服务倾向于依赖 Symfony 中的其他服务,这些服务也必须被模拟),但是需要更多的努力来确保通过测试意味着它会处理您希望它处理的数据。

此外,对数据库进行单元测试是出了名的困难,而且很少被讨论。我不确定我分享的是否是“最佳”答案,但这是一个对我有用的答案,它有助于对实际服务进行单元测试。因此,我发现它是一种比模拟服务更有效的测试方法。

这是基于一篇很棒的文章,当然,我现在找不到它(如果我找到它,我会更新它以感谢他们)。

基本上,您可以将 bundle 设置为在测试中包含容器。

Composer .json:

"require-dev": {
    "sensio/framework-extra-bundle": ">=3.0",
    "symfony/asset": ">=3.2"
}

然后创建一个 config.yml,其中包含您可能需要的任何服务以及 Symfony 表单的最低限度:

framework:
    secret: 'shh'
    form: ~
    validation: { enable_annotations: true }
    session:
        storage_id: session.storage.mock_file

doctrine:
    # your doctrine settings if you want to test against the DB

创建一个 AppKernel 类。

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        return array(
            new FrameworkBundle(),
            new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
            // any other bundles you need
        );
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config.yml');

    }

    public function getLogDir()
    {
        return '/tmp/log/' . $this->environment;
    }
}

最后,我在我的基本 TestCase 中创建了一个辅助类:

protected function getContainer()
{
    if (!isset($this->kernel)) {
        $this->kernel = new AppKernel('test', true);
        $this->kernel->boot();
    }
    if (!isset($this->container)) {
        $this->container = $this->kernel->getContainer();
    }
    return $this->container;
}

现在您可以像这样访问您已注册的任何服务:

public function testContainerAccess()
{
    $this->assertTrue(is_object($this->getContainer());
    $this->assertTrue($this->getContainer()->get('doctrine.orm.entity_manager') instanceof \Doctrine\ORM\EntityManagerInterface);
}

针对数据库的测试总是很棘手,并且是一个单独的蠕虫病毒。在这种情况下,最简单的做法可能是创建一个单独的测试架构并针对它运行查询。

希望这对您有所帮助。

关于php - Symfony FormType 测试处理 EntityType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080027/

相关文章:

php - Highcharts 深入图表 CodeIgniter

html - 将表单添加到 html 电子邮件通讯

unit-testing - 模拟 HttpContext.Current.ApplicationInstance.Response

ruby - Rspec 测试 : it { should respond_to() }

php - 如何在 Joomla! 中插入 HTML 标签模块标题?

php - 如果尚未定义新列,是否会使用 php 函数 "insert into"创建新列,或者返回错误?

javascript - HTML 不会在 Bootstrap Modal 中动态添加表单字段的值属性

forms - 如何在GWT 中实现服务器端防止双重提交?

java - 使用mockito powermokito 模拟重写方法

php - 我什么时候应该在我的数据库中使用静态数组而不是新表?