Symfony2 accesses private services in tests

I am currently working on testing some services in Symfony2 and I am trying to use the Guzzle MockPlugin to manage CURL responses. Version 2.3.8 of Symfony is used. I have interesting behavior and I'm not sure if this is a Symfony2 bug or not.

I have these services in services.yml:

lookup_service_client:
    class: FOO
    public: false
    factory_service: lookup_client_builder
    factory_method: build

lookup_repository_auth_type:
    class: AuthType
    arguments: ["@lookup_service_client"]

lookup_repository_cancel_reason:
    class: CancelReason
    arguments: ["@lookup_service_client"]

payment_service_client:
    class: FOO
    public: false
    factory_service: payment_client_builder
    factory_method: build

payment_repository:
    class: Payment
    arguments: ["@payment_service_client"]

      

The name of the classes is not important. You can see that "lookup_service_client" and "lookup_service_client" are PRIVATE services.

I have a test class that extends Symfony \ Bundle \ FrameworkBundle \ Test \ WebTestCase. In one test, I need to do something like:

$lookup = $this->client->getContainer()->get('lookup_service_client');

$payment = $this->client->getContainer()->get('payment_service_client');

      

I expected that setting these services as PRIVATE would not allow me to get services from the container in tests, but the actual result is:

$lookup = $this->client->getContainer()->get('lookup_service_client'); => returns the service instance

$payment = $this->client->getContainer()->get('payment_service_client'); => returns an exception saying: "You have requested a non-existent service"

      

The only difference between these pull service_client services is that "lookup_service_client" is injected into several other services, while "payment_service_client" is injected into only one other service.

So the questions:

  • Why can I get the "lookup_service_client" from the container since I set it to private?

  • Why can I get "lookup_service_client" but cannot get "payment_service_client" as the only difference is above?

  • Is the Symfony2 error accessing a private service?

+3


source to share


2 answers


While this is not a mistake, it is certainly counter intuitive. The manual states:

Now that the service is closed, you shouldn't be receiving the service directly from the container:

$container->get('foo');

This may or may not work, depending on how the service container is optimized, and even in cases where it does, is deprecated. Simply said, a service can be marked as private if you don't want to access it directly from your code.



This is why the core team decided to make this behavior more consistent and intuitive in Symfony 4:

Setting or disabling a private service using the Container :: set () method was deprecated in Symfony 3.2 and is no longer supported in 4.0;

Checking for the existence of a private service with a container :: has () always returns false in Symfony 4.0;

Requesting a private service using the Container :: get () method was deprecated in Symfony 3.2 and no longer returns a service in 4.0.

+1


source


Check them out in the container:

container:debug lookup_service_client

container:debug payment_service_client

      



in your example they both have class "FOO", it is possible that case

0


source







All Articles