symfony-docs
symfony-docs copied to clipboard
Symfony docs should explain how to 1. use and overwrite services in 6.x and 2. that all need to be public in test
https://symfony.com/doc/current/testing.html
lacks information of say
class UnderstandSymfonyTest extends KernelTestCase
{
...
self::getContainer()->set(IDevJobService::class, $mockDevJobService);
...
and that all services need to be set to public in test to use them e.g.
when@test:
services:
App\Service\Concerns\IDevJobService:
class: App\Tests\Classes\TestDevJobService
autowire: true
public: true
Does the Retrieving Services in the Test section answer your question? The note at the end of this section explains how to access to private services.
I don't understand the examples, it looks like a mock service is injected in the second code block, and it is replaced by another mock in the first code block.
first code block shows how you can inject a mock service at runtime - or any other class. The reason to use it that way is to set the service at runtime to what you want it to be during testing. For all code references
second shows how you set a service to public (this gets overwritten by first code block)
if you want to leave out how to set a test service to public, then leave out the second block. maybe move the note to the top, right below the heading.
the first one is important though imho
Someone in the symfony slack asked why they were receiving a concrete CurlClient instead of a MockHttpClient in their test.
They were specifically confused by this wording:
MockHttpClient implements the HttpClientInterface, just like any actual HTTP client in this component. When you type-hint with HttpClientInterface your code will accept the real client outside tests, while replacing it with MockHttpClient in the test.
And thought it implied the service container would use the mock in the test environment automatically.
The solution was to use the container->set(...) method in their test to swap out the real client for the mock, but there is a lack of documentation referencing it. The only example I could find (very similar to the one provided by torian) was provided by Nicolas Grekas in this pr.
I think having it as part of the Mocking Dependencies section of the Testing docs would be great as I agree that it's very important. (I found out about it from my IDE, but wasn't sure if it was an appropriate method to use in testing). And then also adding another example to, or changing the current example, in the FullExample section of the HttpClient docs (using set would be less verbose than manually instantiating services).
and that all services need to be set to public in test to use them e.g.
when@test: services: App\Service\Concerns\IDevJobService: class: App\Tests\Classes\TestDevJobService autowire: true public: true
I don't understand why the autowire: true is required here.
Here is the default config for services:
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
To my knowledge, it should be inherited by the services in the [email protected] block, isn't it?
It looks like users have to declare the autowiring globally for the test services, like this:
when@test:
services:
_defaults:
autowire: true
autoconfigure: true
App\DataFixtures\ORM\:
resource: '../src/DataFixtures/ORM/*'
tags: [ 'doctrine.fixture.orm' ]
Or for every service:
when@test:
services:
App\DataFixtures\ORM\:
resource: '../src/DataFixtures/ORM/*'
autowire: true
tags: [ 'doctrine.fixture.orm' ]
(this is not a support question, I just want to ensure that we will use the right syntax when we'll update the docs)
I think the updated testing contents already cover what this issue asked for:
- Mocking dependencies, setting services in container: https://symfony.com/doc/current/testing.html#mocking-dependencies
- Getting public/private services from the container in tests: https://symfony.com/doc/current/testing.html#retrieving-services-in-the-test
So, I'm closing this as fixed. If there's something missing, please add a comment and we'll take care of it. Thanks!