Skip to content

Commit 3ccb220

Browse files
committed
[#2012] Proofreading the new unit testing form types chapter
1 parent 91171ac commit 3ccb220

File tree

3 files changed

+39
-40
lines changed

3 files changed

+39
-40
lines changed

cookbook/form/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ Form
1111
create_custom_field_type
1212
create_form_type_extension
1313
use_virtuals_forms
14+
unit_testing

cookbook/form/unit_testing.rst

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
11
.. index::
22
single: Form; Form testing
33

4-
Testing forms
5-
=============
4+
How to Unit Test your Forms
5+
===========================
66

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
88
:class:`Symfony\\Component\\Form\\FormTypeInterface`), the
99
:class:`Symfony\\Component\\Form\\Form` and the
1010
:class:`Symfony\\Component\\Form\\FormView`.
1111

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
1515
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.
1818

1919
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.
2322

2423
.. note::
25-
24+
2625
Depending on the way you installed your Symfony or Symfony Form Component
2726
the tests may not be downloaded. Use the --prefer-source option with
2827
composer if this is the case.
2928

3029
The Basics
3130
----------
3231

33-
The simplest TypeTestCase implementation looks like the following::
32+
The simplest ``TypeTestCase`` implementation looks like the following::
3433

3534
// src/Acme/TestBundle/Tests/Form/Type/TestedTypeTests.php
3635
namespace Acme\TestBundle\Tests\Form\Type;
@@ -70,34 +69,32 @@ The simplest TypeTestCase implementation looks like the following::
7069

7170
So, what does it test? Let's explain it line by line.
7271

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
7574
be the first test you write::
7675

7776
$type = new TestedType();
7877
$form = $this->factory->create($type);
7978

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::
8482

8583
$form->bind($formData);
8684
$this->assertTrue($form->isSynchronized());
8785

8886
.. note::
8987

90-
We don't check the validationit is done by a listener that is not
88+
Don't test the validation: it is applied by a listener that is not
9189
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.
9491

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
9693
checks if all the fields are correctly specified::
9794

9895
$this->assertEquals($object, $form->getData());
9996

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
10198
widgets you want to display are available in the children property::
10299

103100
$view = $form->createView();
@@ -107,18 +104,18 @@ widgets you want to display are available in the children property::
107104
$this->assertArrayHasKey($key, $children);
108105
}
109106

110-
Adding a Type your form depends on
107+
Adding a Type your Form depends on
111108
----------------------------------
112109

113110
Your form may depend on other types that are defined as services. It
114-
would be defined like this::
111+
might look like this::
115112

116113
// src/Acme/TestBundle/Form/Type/TestedType.php
117114

118115
// ... the buildForm method
119116
$builder->add('acme_test_child_type');
120117

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
122119
form factory in your test. The easiest way is to register it manually
123120
before creating the parent form::
124121

@@ -137,7 +134,7 @@ before creating the parent form::
137134

138135
$type = new TestedType();
139136
$form = $this->factory->create($type);
140-
137+
141138
// ... your test
142139
}
143140
}
@@ -148,15 +145,15 @@ before creating the parent form::
148145
be getting errors that are not related to the form you are currently
149146
testing but to its children.
150147

151-
Adding custom extensions
148+
Adding custom Extensions
152149
------------------------
153150

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::
160157

161158
// src/Acme/TestBundle/Tests/Form/Type/TestedTypeTests.php
162159
namespace Acme\TestBundle\Tests\Form\Type;
@@ -193,11 +190,11 @@ add the dependencies to the Factory object::
193190
// ... your tests
194191
}
195192

196-
Testing against different sets of data
193+
Testing against different Sets of Data
197194
--------------------------------------
198195

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::
201198

202199
// src/Acme/TestBundle/Tests/Form/Type/TestedTypeTests.php
203200
namespace Acme\TestBundle\Tests\Form\Type;
@@ -244,6 +241,6 @@ data. This allows for decoupling the test fixtures from the tests and
244241
easily testing against multiple sets of data.
245242

246243
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.
248245

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

cookbook/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
* :doc:`/cookbook/form/create_custom_field_type`
8282
* :doc:`/cookbook/form/create_form_type_extension`
8383
* :doc:`/cookbook/form/use_virtuals_forms`
84+
* :doc:`/cookbook/form/unit_testing`
8485
* (validation) :doc:`/cookbook/validation/custom_constraint`
8586
* (doctrine) :doc:`/cookbook/doctrine/file_uploads`
8687

0 commit comments

Comments
 (0)