Skip to content

Commit 917c9db

Browse files
committed
[Testing] Add a section to mock service dependencies
1 parent c0f4dd4 commit 917c9db

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

testing.rst

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,92 @@ It gives you access to both the public services and the non-removed
280280
are not used by any other services), you need to declare those private
281281
services as public in the ``config/services_test.yaml`` file.
282282

283+
Mocking Dependencies
284+
--------------------
285+
286+
Sometimes it can be useful to mock a dependency of a tested service.
287+
288+
From the example in the previous section, let's assume the
289+
``NewsletterGenerator`` has a dependency to a private alias
290+
``NewsRepositoryInterface`` pointing to a private ``NewsRepository`` service
291+
and we would like to use a mocked ``NewsRepositoryInterface`` instead of the
292+
concrete one::
293+
294+
// ...
295+
use App\Contracts\Repository\NewsRepositoryInterface;
296+
297+
class NewsletterGeneratorTest extends KernelTestCase
298+
{
299+
public function testSomething()
300+
{
301+
// ... same bootstrap as the section above
302+
303+
$newsRepository = $this->createMock(NewsRepositoryInterface::class);
304+
$newsRepository->expects(self::once())
305+
->method('findNewsFromLastMonth')
306+
->willReturn([
307+
new News('some news'),
308+
new News('some other news'),
309+
])
310+
;
311+
312+
// the following line won't work unless the alias is made public
313+
$container->set(NewsRepositoryInterface::class, $newsRepository);
314+
315+
// will be injected the mocked repository
316+
$newsletterGenerator = $container->get(NewsletterGenerator::class);
317+
318+
// ...
319+
}
320+
}
321+
322+
In order to make the alias public, you will need to update configuration for
323+
the ``test`` environment as follow:
324+
325+
.. configuration-block::
326+
327+
.. code-block:: yaml
328+
329+
# config/services_test.yaml
330+
services:
331+
# redefine the alias as it should be while making it public
332+
App\Contracts\Repository\NewsRepositoryInterface:
333+
alias: App\Repository\NewsRepository
334+
public: true
335+
336+
.. code-block:: xml
337+
338+
<!-- config/services_test.xml -->
339+
<?xml version="1.0" encoding="UTF-8" ?>
340+
<container xmlns="http://symfony.com/schema/dic/services"
341+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
342+
xsi:schemaLocation="http://symfony.com/schema/dic/services
343+
https://symfony.com/schema/dic/services/services-1.0.xsd
344+
">
345+
<services>
346+
<!-- redefine the alias as it should be while making it public -->
347+
<service id="App\Contracts\Repository\NewsRepositoryInterface"
348+
alias="App\Repository\NewsRepository"
349+
/>
350+
</services>
351+
</container>
352+
353+
.. code-block:: php
354+
355+
// config/services_test.php
356+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
357+
358+
use App\Contracts\Repository\NewsRepositoryInterface;
359+
use App\Repository\NewsRepository;
360+
361+
return static function (ContainerConfigurator $container) {
362+
$container->services()
363+
// redefine the alias as it should be while making it public
364+
->alias(NewsRepositoryInterface::class, NewsRepository::class)
365+
->public()
366+
;
367+
};
368+
283369
.. _testing-databases:
284370

285371
Configuring a Database for Tests

0 commit comments

Comments
 (0)