Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit de83642

Browse files
committed
minor #13552 [Form] Updated unit testing article (HeahDude)
This PR was squashed before being merged into the 3.4 branch. Discussion ---------- [Form] Updated unit testing article Ref symfony/symfony#36462. Commits ------- de0d1fb [Form] Updated unit testing article
2 parents 63f48cb + de0d1fb commit de83642

File tree

1 file changed

+57
-30
lines changed

1 file changed

+57
-30
lines changed

form/unit_testing.rst

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ factory but it would be complex. It is better to pass it to FormFactory like it
2323
is done in a real application. It is simple to bootstrap and you can trust
2424
the 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,35 @@ 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()
82+
;
7483

75-
foreach (array_keys($formData) as $key) {
76-
$this->assertArrayHasKey($key, $children);
77-
}
84+
$this->assertArrayHasKey('custom_var', $view->vars);
85+
$this->assertSame('expected value', $view->vars['custom_var']);
7886
}
7987
}
8088

@@ -84,7 +92,7 @@ First you verify if the ``FormType`` compiles. This includes basic class
8492
inheritance, the ``buildForm()`` function and options resolution. This should
8593
be the first test you write::
8694

87-
$form = $this->factory->create(TestedType::class, $objectToCompare);
95+
$form = $this->factory->create(TestedType::class, $formData);
8896

8997
This test checks that none of your data transformers used by the form
9098
failed. The :method:`Symfony\\Component\\Form\\FormInterface::isSynchronized`
@@ -97,30 +105,38 @@ method is only set to ``false`` if a data transformer throws an exception::
97105

98106
Don't test the validation: it is applied by a listener that is not
99107
active in the test case and it relies on validation configuration.
100-
Instead, unit test your custom constraints directly.
108+
Instead, unit test your custom constraints directly or read how
109+
to :ref:`add custom extensions <form_unit_testing-adding_custom_extensions>`
110+
in the last section of this page.
101111

102-
Next, verify the submission and mapping of the form. The test below
103-
checks if all the fields are correctly specified::
112+
Next, verify the submission and mapping of the form. The test below checks if
113+
all the fields are correctly specified::
104114

105-
$this->assertEquals($object, $objectToCompare);
115+
$this->assertEquals($expected, $formData);
106116

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::
117+
Finally, check the creation of the ``FormView``. You can check that a custom
118+
variable exists and will be available in your form themes::
109119

110-
$view = $form->createView();
111-
$children = $view->children;
112-
113-
foreach (array_keys($formData) as $key) {
114-
$this->assertArrayHasKey($key, $children);
115-
}
120+
$this->assertArrayHasKey('custom_var', $view->vars);
121+
$this->assertSame('expected value', $view->vars['custom_var']);
116122

117123
.. tip::
118124

119125
Use :ref:`PHPUnit data providers <testing-data-providers>` to test multiple
120126
form conditions using the same test code.
121127

122-
Testings Types from the Service Container
123-
-----------------------------------------
128+
.. caution::
129+
130+
When your type relies on the ``EntityType``, you should register the
131+
:class:`Symfony\\Bridge\\Doctrine\\Form\\DoctrineOrmExtension`, which will
132+
need to mock the ``ManagerRegistry``.
133+
134+
However, If you cannot use a mock to write your test, you should extend
135+
the ``KernelTestCase`` instead and use the ``form.factory`` service to
136+
create the form.
137+
138+
Testings Types Registered as Services
139+
-------------------------------------
124140

125141
Your form may be used as a service, as it depends on other services (e.g. the
126142
Doctrine entity manager). In these cases, using the above code won't work, as
@@ -165,14 +181,18 @@ make sure the ``FormRegistry`` uses the created instance::
165181

166182
public function testSubmitValidData()
167183
{
184+
// ...
185+
168186
// Instead of creating a new instance, the one created in
169187
// getExtensions() will be used.
170-
$form = $this->factory->create(TestedType::class);
188+
$form = $this->factory->create(TestedType::class, $formData);
171189

172190
// ... your test
173191
}
174192
}
175193

194+
.. _form_unit_testing-adding_custom_extensions:
195+
176196
Adding Custom Extensions
177197
------------------------
178198

@@ -211,6 +231,13 @@ allows you to return a list of extensions to register::
211231
// ... your tests
212232
}
213233

234+
.. note::
235+
236+
By Default only the
237+
:class:`Symfony\\Component\\Form\\Extension\\Core\\CoreExtension` is
238+
registered in tests. You can find other extensions from the Form component
239+
in the ``Symfony\Component\Form\Extension`` namespace.
240+
214241
It is also possible to load custom form types, form type extensions or type
215242
guessers using the :method:`Symfony\\Component\\Form\\Test\\FormIntegrationTestCase::getTypes`,
216243
:method:`Symfony\\Component\\Form\\Test\\FormIntegrationTestCase::getTypeExtensions`

0 commit comments

Comments
 (0)