cre*_*lem 16 php forms unit-testing symfony
我对Symfony FormType测试提出了一个问题.http://symfony.com/doc/current/cookbook/form/unit_testing.html
在我的表单类型中,entity类型很常见.使用doctrine实体表单类型测试表单类型是可怕的.
这是我的表格领域.
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
));
}
Run Code Online (Sandbox Code Playgroud)
这是该领域的模拟.
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;
}
Run Code Online (Sandbox Code Playgroud)
这真的是正确的方法吗?在TypeTestCase我内部没有访问任何东西,没有容器没有内核,没有.这使得测试表单类型非常困难和令人沮丧.
有没有更好的方法来测试表单类型?或者更简单的方法来处理具有ORM依赖的类型?
干杯.
我在对大量依赖服务容器的东西进行单元测试时遇到了困难。起初我尝试嘲笑一切,就像你一样。这可以使单元测试通过很大的努力(服务倾向于依赖 Symfony 中的其他服务,这些服务也必须被模拟),但是需要更多的努力来确保通过测试意味着它将使用您希望它使用的数据。
此外,众所周知,对数据库进行单元测试非常困难并且很少被讨论。我不确定我分享的是否是“最佳”答案,但这是一个对我有用的答案,它有助于对真正的服务进行单元测试。因此,我发现它是比模拟服务更有效的测试方法。
这是基于一篇很棒的文章,当然,我现在找不到它(如果我找到它以归功于他们,我会更新它)。
基本上,您可以将捆绑包设置为在测试中包含容器。
作曲家.json:
"require-dev": {
"sensio/framework-extra-bundle": ">=3.0",
"symfony/asset": ">=3.2"
}
Run Code Online (Sandbox Code Playgroud)
然后创建一个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
Run Code Online (Sandbox Code Playgroud)
创建一个 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;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我在我的基本测试用例中创建一个帮助器类:
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;
}
Run Code Online (Sandbox Code Playgroud)
现在您可以访问您已注册的任何服务,如下所示:
public function testContainerAccess()
{
$this->assertTrue(is_object($this->getContainer());
$this->assertTrue($this->getContainer()->get('doctrine.orm.entity_manager') instanceof \Doctrine\ORM\EntityManagerInterface);
}
Run Code Online (Sandbox Code Playgroud)
对数据库进行测试总是很棘手,并且是一个单独的蠕虫罐头。在这种情况下,最简单的事情可能是创建一个单独的测试模式并针对它运行查询。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
1487 次 |
| 最近记录: |