@@ -23,9 +23,9 @@ factory but it would be complex. It is better to pass it to FormFactory like it
2323is done in a real application. It is simple to bootstrap and you can trust
2424the Symfony components enough to use them as a testing base.
2525
26- There is already a class that you can benefit from for simple FormTypes
27- testing: : class: `Symfony\\ Component\\ Form\\ Test\\ TypeTestCase `. It is used to
28- test the core types and you can use it to test your types too.
26+ There is already a class that you can benefit from for testing:
27+ : class: `Symfony\\ Component\\ Form\\ Test\\ TypeTestCase `. It is used to test the
28+ core types and you can use it to test your types too.
2929
3030.. note ::
3131
@@ -54,27 +54,34 @@ The simplest ``TypeTestCase`` implementation looks like the following::
5454 'test2' => 'test2',
5555 ];
5656
57- $objectToCompare = new TestObject();
58- // $objectToCompare will retrieve data from the form submission; pass it as the second argument
59- $form = $this->factory->create(TestedType::class, $objectToCompare );
57+ $formData = new TestObject();
58+ // $formData will retrieve data from the form submission; pass it as the second argument
59+ $form = $this->factory->create(TestedType::class, $formData );
6060
61- $object = new TestObject();
61+ $expected = new TestObject();
6262 // ...populate $object properties with the data stored in $formData
6363
6464 // submit the data to the form directly
6565 $form->submit($formData);
6666
67+ // This check ensures there are no transformation failures
6768 $this->assertTrue($form->isSynchronized());
6869
69- // check that $objectToCompare was modified as expected when the form was submitted
70- $this->assertEquals($object, $objectToCompare);
70+ // check that $formData was modified as expected when the form was submitted
71+ $this->assertEquals($expected, $formData);
72+ }
73+
74+ public function testCustomFormView()
75+ {
76+ $formData = new TestObject();
77+ // ... prepare the data as you need
7178
72- $view = $form->createView();
73- $children = $view->children;
79+ // The initial data may be used to compute custom view variables
80+ $view = $this->factory->create(TestedType::class, $formData)
81+ ->createView();
7482
75- foreach (array_keys($formData) as $key) {
76- $this->assertArrayHasKey($key, $children);
77- }
83+ $this->assertArrayHasKey('custom_var', $view->vars);
84+ $this->assertSame('expected value', $view->vars['custom_var']);
7885 }
7986 }
8087
@@ -84,7 +91,7 @@ First you verify if the ``FormType`` compiles. This includes basic class
8491inheritance, the ``buildForm() `` function and options resolution. This should
8592be the first test you write::
8693
87- $form = $this->factory->create(TestedType::class, $objectToCompare );
94+ $form = $this->factory->create(TestedType::class, $formData );
8895
8996This test checks that none of your data transformers used by the form
9097failed. The :method: `Symfony\\ Component\\ Form\\ FormInterface::isSynchronized `
@@ -97,30 +104,38 @@ method is only set to ``false`` if a data transformer throws an exception::
97104
98105 Don't test the validation: it is applied by a listener that is not
99106 active in the test case and it relies on validation configuration.
100- Instead, unit test your custom constraints directly.
107+ Instead, unit test your custom constraints directly or read how
108+ to :ref: `add custom extensions <form_unit_testing-adding_custom_extensions >`
109+ in the last section of this page.
101110
102- Next, verify the submission and mapping of the form. The test below
103- checks if all the fields are correctly specified::
111+ Next, verify the submission and mapping of the form. The test below checks if
112+ all the fields are correctly specified::
104113
105- $this->assertEquals($object , $objectToCompare );
114+ $this->assertEquals($expected , $formData );
106115
107- Finally, check the creation of the ``FormView ``. You should check if all
108- widgets you want to display are available in the children property ::
116+ Finally, check the creation of the ``FormView ``. You can check that a custom
117+ variable exists and will be available in your form themes ::
109118
110- $view = $form->createView();
111- $children = $view->children;
112-
113- foreach (array_keys($formData) as $key) {
114- $this->assertArrayHasKey($key, $children);
115- }
119+ $this->assertArrayHasKey('custom_var', $view->vars);
120+ $this->assertSame('expected value', $view->vars['custom_var']);
116121
117122.. tip ::
118123
119124 Use :ref: `PHPUnit data providers <testing-data-providers >` to test multiple
120125 form conditions using the same test code.
121126
122- Testings Types from the Service Container
123- -----------------------------------------
127+ .. caution ::
128+
129+ When your type relies on the ``EntityType ``, you should register the
130+ :class: `Symfony\\ Bridge\\ Doctrine\\ Form\\ DoctrineOrmExtension `, which will
131+ need to mock the ``ManagerRegistry ``.
132+
133+ However, If you cannot use a mock to write your test, you should extend
134+ the ``KernelTestCase `` instead and use the ``form.factory `` service to
135+ create the form.
136+
137+ Testings Types Registered as Services
138+ -------------------------------------
124139
125140Your form may be used as a service, as it depends on other services (e.g. the
126141Doctrine entity manager). In these cases, using the above code won't work, as
@@ -165,14 +180,18 @@ make sure the ``FormRegistry`` uses the created instance::
165180
166181 public function testSubmitValidData()
167182 {
183+ // ...
184+
168185 // Instead of creating a new instance, the one created in
169186 // getExtensions() will be used.
170- $form = $this->factory->create(TestedType::class);
187+ $form = $this->factory->create(TestedType::class, $formData );
171188
172189 // ... your test
173190 }
174191 }
175192
193+ .. _form_unit_testing-adding_custom_extensions :
194+
176195Adding Custom Extensions
177196------------------------
178197
@@ -211,6 +230,13 @@ allows you to return a list of extensions to register::
211230 // ... your tests
212231 }
213232
233+ .. note ::
234+
235+ By default only the
236+ :class: `Symfony\\ Component\\ Form\\ Extension\\ Core\\ CoreExtension ` is
237+ registered in tests. You can find other extensions from the Form component
238+ in the ``Symfony\Component\Form\Extension `` namespace.
239+
214240It is also possible to load custom form types, form type extensions or type
215241guessers using the :method: `Symfony\\ Component\\ Form\\ Test\\ FormIntegrationTestCase::getTypes `,
216242:method: `Symfony\\ Component\\ Form\\ Test\\ FormIntegrationTestCase::getTypeExtensions `
0 commit comments