1
1
.. index ::
2
2
single: Form; Form testing
3
3
4
- Testing forms
5
- =============
4
+ How to Unit Test your Forms
5
+ ===========================
6
6
7
- The Form Component consists of 3 core objects: a FormType (implementing
7
+ The Form Component consists of 3 core objects: a form type (implementing
8
8
:class: `Symfony\\ Component\\ Form\\ FormTypeInterface `), the
9
9
:class: `Symfony\\ Component\\ Form\\ Form ` and the
10
10
:class: `Symfony\\ Component\\ Form\\ FormView `.
11
11
12
- The only class that is usually manipulated by programmers is the FormType class
13
- which serves as a form blueprint. It is used to generate the Form and the
14
- FormView. You could test it directly by mocking its interactions with the
12
+ The only class that is usually manipulated by programmers is the form type class
13
+ which serves as a form blueprint. It is used to generate the `` Form `` and the
14
+ `` FormView `` . You could test it directly by mocking its interactions with the
15
15
factory but it would be complex. It is better to pass it to FormFactory like it
16
- is done in a real application. It is simple to bootstrap and we trust Symfony
17
- components enough to use them as a testing base.
16
+ is done in a real application. It is simple to bootstrap and you can trust
17
+ the Symfony components enough to use them as a testing base.
18
18
19
19
There is already a class that you can benefit from for simple FormTypes
20
- testing, the
21
- :class: `Symfony\\ Component\\ Form\\ Tests\\ Extension\\ Core\\ Type\\ TypeTestCase `.
22
- It is used to test the core types and you can use it to test yours too.
20
+ testing: :class: `Symfony\\ Component\\ Form\\ Tests\\ Extension\\ Core\\ Type\\ TypeTestCase `.
21
+ It is used to test the core types and you can use it to test your types too.
23
22
24
23
.. note ::
25
-
24
+
26
25
Depending on the way you installed your Symfony or Symfony Form Component
27
26
the tests may not be downloaded. Use the --prefer-source option with
28
27
composer if this is the case.
29
28
30
29
The Basics
31
30
----------
32
31
33
- The simplest TypeTestCase implementation looks like the following::
32
+ The simplest `` TypeTestCase `` implementation looks like the following::
34
33
35
34
// src/Acme/TestBundle/Tests/Form/Type/TestedTypeTests.php
36
35
namespace Acme\TestBundle\Tests\Form\Type;
@@ -70,34 +69,32 @@ The simplest TypeTestCase implementation looks like the following::
70
69
71
70
So, what does it test? Let's explain it line by line.
72
71
73
- First we verify if the FormType compiles. This includes basic class
74
- inheritance, the buildForm function and options resolution. This should
72
+ First you verify if the `` FormType `` compiles. This includes basic class
73
+ inheritance, the `` buildForm `` function and options resolution. This should
75
74
be the first test you write::
76
75
77
76
$type = new TestedType();
78
77
$form = $this->factory->create($type);
79
78
80
-
81
- This test checks if none of your DataTransformers used by the form
82
- failed. The isSynchronized is only set to false if a DataTransformer
83
- throws an exception::
79
+ This test checks that none of your data transformers used by the form
80
+ failed. The :method: `Symfony\\ Component\\ Form\\ FormInterface::isSynchronized` `
81
+ method is only set to ``false `` if a data transformer throws an exception::
84
82
85
83
$form->bind($formData);
86
84
$this->assertTrue($form->isSynchronized());
87
85
88
86
.. note ::
89
87
90
- We don 't check the validation – it is done by a listener that is not
88
+ Don 't test the validation: it is applied by a listener that is not
91
89
active in the test case and it relies on validation configuration.
92
- You would need to bootstrap the whole kernel to do it. Write
93
- separate tests to check your validators.
90
+ Instead, unit test your custom constraints directly.
94
91
95
- Next we verify the binding and mapping of the form. The test below
92
+ Next, verify the binding and mapping of the form. The test below
96
93
checks if all the fields are correctly specified::
97
94
98
95
$this->assertEquals($object, $form->getData());
99
96
100
- At last we check the creation of the FormView. You should check if all
97
+ Finally, check the creation of the `` FormView `` . You should check if all
101
98
widgets you want to display are available in the children property::
102
99
103
100
$view = $form->createView();
@@ -107,18 +104,18 @@ widgets you want to display are available in the children property::
107
104
$this->assertArrayHasKey($key, $children);
108
105
}
109
106
110
- Adding a Type your form depends on
107
+ Adding a Type your Form depends on
111
108
----------------------------------
112
109
113
110
Your form may depend on other types that are defined as services. It
114
- would be defined like this::
111
+ might look like this::
115
112
116
113
// src/Acme/TestBundle/Form/Type/TestedType.php
117
114
118
115
// ... the buildForm method
119
116
$builder->add('acme_test_child_type');
120
117
121
- To create your form correctly you need to make the type available to the
118
+ To create your form correctly, you need to make the type available to the
122
119
form factory in your test. The easiest way is to register it manually
123
120
before creating the parent form::
124
121
@@ -137,7 +134,7 @@ before creating the parent form::
137
134
138
135
$type = new TestedType();
139
136
$form = $this->factory->create($type);
140
-
137
+
141
138
// ... your test
142
139
}
143
140
}
@@ -148,15 +145,15 @@ before creating the parent form::
148
145
be getting errors that are not related to the form you are currently
149
146
testing but to its children.
150
147
151
- Adding custom extensions
148
+ Adding custom Extensions
152
149
------------------------
153
150
154
- It often happens that you use some options that are added by form
155
- extensions. One of the cases may be the ValidatorExtension with its
156
- invalid_message option. The TypeTestCase loads only the core Form
157
- Extension so an “Invalid option” exception will be raised if you try to
158
- use it for testing a class that depends on other extensions. You need
159
- add the dependencies to the Factory object::
151
+ It often happens that you use some options that are added by
152
+ :doc: ` form extensions<cookbook/form/create_form_type_extension> `. One of the
153
+ cases may be the `` ValidatorExtension `` with its `` invalid_message `` option.
154
+ The `` TypeTestCase `` loads only the core form extension so an "Invalid option"
155
+ exception will be raised if you try to use it for testing a class that depends
156
+ on other extensions. You need add those extensions to the factory object::
160
157
161
158
// src/Acme/TestBundle/Tests/Form/Type/TestedTypeTests.php
162
159
namespace Acme\TestBundle\Tests\Form\Type;
@@ -193,11 +190,11 @@ add the dependencies to the Factory object::
193
190
// ... your tests
194
191
}
195
192
196
- Testing against different sets of data
193
+ Testing against different Sets of Data
197
194
--------------------------------------
198
195
199
- If you are not familiar yet with PHPUnit's `data providers `_ it would be
200
- a good opportunity to use them::
196
+ If you are not familiar yet with PHPUnit's `data providers `_, this might be
197
+ a good opportunity to use them::
201
198
202
199
// src/Acme/TestBundle/Tests/Form/Type/TestedTypeTests.php
203
200
namespace Acme\TestBundle\Tests\Form\Type;
@@ -244,6 +241,6 @@ data. This allows for decoupling the test fixtures from the tests and
244
241
easily testing against multiple sets of data.
245
242
246
243
You can also pass another argument, such as a boolean if the form has to
247
- be synchronized with the given set of data or not etc.
244
+ be synchronized with the given set of data or not etc.
248
245
249
- .. _`data providers` : http://www.phpunit.de/manual/3.7 /en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers
246
+ .. _`data providers` : http://www.phpunit.de/manual/current /en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers
0 commit comments