Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b022d23

Browse filesBrowse files
committed
Merge branch '2.0' into 2.1
2 parents f6c6896 + 09d3e18 commit b022d23
Copy full SHA for b022d23

File tree

Expand file treeCollapse file tree

4 files changed

+153
-1
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+153
-1
lines changed

‎book/internals.rst

Copy file name to clipboardExpand all lines: book/internals.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ variables:
4646

4747
.. note::
4848

49-
Read more about the :doc:`HttpFoundation Component </components/http_foudation/introduction>`.
49+
Read more about the :doc:`HttpFoundation Component </components/http_foundation/introduction>`.
5050

5151
``HttpKernel`` Component
5252
~~~~~~~~~~~~~~~~~~~~~~~~

‎cookbook/map.rst.inc

Copy file name to clipboardExpand all lines: cookbook/map.rst.inc
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
* :doc:`/cookbook/testing/simulating_authentication`
150150
* :doc:`/cookbook/testing/insulating_clients`
151151
* :doc:`/cookbook/testing/profiling`
152+
* :doc:`/cookbook/testing/database`
152153
* :doc:`/cookbook/testing/doctrine`
153154
* :doc:`/cookbook/testing/bootstrap`
154155
* (email) :doc:`/cookbook/email/testing`

‎cookbook/testing/database.rst

Copy file name to clipboard
+150Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
.. index::
2+
single: Tests; Database
3+
4+
How to test code that interacts with the Database
5+
=================================================
6+
7+
If your code interacts with the database, e.g. reads data from or stores data
8+
into it, you need to adjust your tests to take this into account. There are
9+
many ways how to deal with this. In a unit test, you can create a mock for
10+
a ``Repository`` and use it to return expected objects. In a functional test,
11+
you may need to prepare a test database with predefined values to ensure that
12+
your test always has the same data to work with.
13+
14+
.. note::
15+
16+
If you want to test your queries directly, see :doc:`/cookbook/testing/doctrine`.
17+
18+
Mocking the ``Repository`` in a Unit Test
19+
-----------------------------------------
20+
21+
If you want to test code which depends on a doctrine ``Repository`` in isolation,
22+
you need to mock the ``Repository``. Normally you inject the ``EntityManager``
23+
into your class and use it to get the repository. This makes things a little
24+
more difficult as you need to mock both the ``EntityManager`` and your repository
25+
class.
26+
27+
.. tip::
28+
29+
It is possible (and a good idea) to inject your repository directly by
30+
registering your repository as a :doc:`factory service</components/dependency_injection/factories>`
31+
This is a little bit more work to setup, but makes testing easier as you
32+
only need to mock the repository.
33+
34+
Suppose the class you want to test looks like this::
35+
36+
namespace Acme\DemoBundle\Salary;
37+
38+
use Doctrine\Common\Persistence\ObjectManager;
39+
40+
class SalaryCalculator
41+
{
42+
private $entityManager;
43+
44+
public function __construct(ObjectManager $entityManager)
45+
{
46+
$this->entityManager = $entityManager;
47+
}
48+
49+
public function calculateTotalSalary($id)
50+
{
51+
$employeeRepository = $this->entityManager->getRepository('AcmeDemoBundle::Employee');
52+
$employee = $userRepository->find($id);
53+
54+
return $employee->getSalary() + $employee->getBonus();
55+
}
56+
}
57+
58+
Since the ``ObjectManager`` gets injected into the class through the constructor,
59+
it's easy to pass a mock object within a test::
60+
61+
use Acme\DemoBundle\Salary\SalaryCalculator;
62+
63+
class SalaryCalculatorTest extends \PHPUnit_Framework_TestCase
64+
{
65+
66+
public function testCalculateTotalSalary()
67+
{
68+
// First, mock the object to be used in the test
69+
$employee = $this->getMock('\Acme\DemoBundle\Entity\Employee');
70+
$employee->expects($this->once())
71+
->method('getSalary')
72+
->will($this->returnValue(1000));
73+
$employee->expects($this->once())
74+
->method('getBonus')
75+
->will($this->returnValue(1100));
76+
77+
// Now, mock the repository so it returns the mock of the employee
78+
$employeeRepository = $this->getMockBuilder('\Doctrine\ORM\EntityRepository')
79+
->disableOriginalConstructor()
80+
->getMock();
81+
$employeeRepository->expects($this->once())
82+
->method('find')
83+
->will($this->returnValue($employee));
84+
85+
// Last, mock the EntityManager to return the mock of the repository
86+
$entityManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager')
87+
->disableOriginalConstructor()
88+
->getMock();
89+
$entityManager->expects($this->once())
90+
->method('getRepository')
91+
->will($this->returnValue($employeeRepository));
92+
93+
$salaryCalculator = new SalaryCalculator($entityManager);
94+
$this->assertEquals(1100, $salaryCalculator->calculateTotalSalary(1));
95+
}
96+
}
97+
98+
In this example, you are building the mocks from the inside out, first creating
99+
the employee which gets returned by the ``Repository``, which itself gets
100+
returned by the ``EntityManager``. This way, no real class is involved in
101+
testing.
102+
103+
Changing database Settings for functional Tests
104+
-----------------------------------------------
105+
106+
If you have functional tests, you want them to interact with a real database.
107+
Most of the time you want to use a dedicated database connection to make sure
108+
not to overwrite data you entered when developing the application and also
109+
to be able to clear the database before every test.
110+
111+
To do this, you can specify a database configuration which overwrites the default
112+
configuration:
113+
114+
.. code-block:: yaml
115+
116+
# app/config/config_test.yml
117+
doctrine:
118+
# ...
119+
dbal:
120+
host: localhost
121+
dbname: testdb
122+
user: testdb
123+
password: testdb
124+
125+
.. code-block:: xml
126+
127+
<!-- app/config/config_test.xml -->
128+
<doctrine:config>
129+
<doctrine:dbal
130+
host="localhost"
131+
dbname="testdb"
132+
user="testdb"
133+
password="testdb"
134+
>
135+
</doctrine:config>
136+
137+
.. code-block:: php
138+
139+
// app/config/config_test.php
140+
$configuration->loadFromExtension('doctrine', array(
141+
'dbal' => array(
142+
'host' => 'localhost',
143+
'dbname' => 'testdb',
144+
'user' => 'testdb',
145+
'password' => 'testdb',
146+
),
147+
));
148+
149+
Make sure that your database runs on localhost and has the defined database and
150+
user credentials set up.

‎cookbook/testing/index.rst

Copy file name to clipboardExpand all lines: cookbook/testing/index.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ Testing
88
simulating_authentication
99
insulating_clients
1010
profiling
11+
database
1112
doctrine
1213
bootstrap

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.