Reputation: 453
i'm currently struggle with the TypeTestCase from Symfony testing a form type with an constructor. While the offical solution registring a form as a service works well in the application, the same form type cannot be tested with TypeTestCase. Since TypeTestCase extends from FormIntegrationTestCase and extends from \PHPUnit_Framework_TestCase instead from KernelTestCase. The FormFactory in TypeTestCase doesn't/can't look for forms registered as services and throw an error calling phpunit:
Tests\DemoBundle\Form\Type\DemoTypeTest::testSubmitValidData
Missing argument 1 for DemoBundle\Form\Type\DemoType::__construct(), called in /var/www/vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php on line 90 and defined
The only way i've currently see is not serving the dependency via constructor using the optionsResolver in the configureOptions set an required element with the setRequired method for the dependency.
Here the relevant parts from the code:
DemoType.php
[...]
class DemoType extends AbstractType
{
/**
* @var EntityManager
*/
protected $entityManager;
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
[...]
services.yml
app.form.type.demo:
class: DemoBundle\Form\Type\DemoType
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: form.type }
DemoTypeTest.php
[...]
class DemoTypeTest extends TypeTestCase
{
protected function getExtensions()
{
$classMetadata = $this->getMock(ClassMetadata::class, [], [], '', false);
/* @var ValidatorInterface|\PHPUnit_Framework_MockObject_MockObject $validator */
$validator = $this->getMock(ValidatorInterface::class);
$validator->method('validate')->will($this->returnValue(new ConstraintViolationList()));
$validator->method('getMetadataFor')->will($this->returnValue($classMetadata));
return [
new ValidatorExtension($validator),
];
}
public function testSubmitValidData()
{
$formData = [
'some' => 'data',
];
$form = $this->factory->create(DemoType::class);
[...]
Upvotes: 4
Views: 3854
Reputation: 39380
You can instantiate the FormType and pass it to the form factory, as described in the doc.
You can mock the Doctrine Entity Manager, as example:
public function testSubmitValidData()
{
// Mock the FormType: entity
$em = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
->disableOriginalConstructor()
->getMock();
$type = new DemoType($em);
$formData = [
'some' => 'data',
];
$form = $this->factory->create($type);
...
A sample about mocking the Doctrine Object Stack for simulate a repo method you can take a look at this answer or simply ask :)
Hope this help
Upvotes: 1