8000 Impossible to get private services from TestContainer · Issue #30104 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Impossible to get private services from TestContainer #30104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lelledev opened this issue Feb 7, 2019 · 13 comments
Closed

Impossible to get private services from TestContainer #30104

lelledev opened this issue Feb 7, 2019 · 13 comments

Comments

@lelledev
Copy link
lelledev commented Feb 7, 2019

Hi there,

Symfony version(s) affected: 4.2.3

Description
An old PR #26499 should allow us to use private services in test env as public.
On my local, I am struggling to make it work. Post here

How to reproduce

  • Install the latest version of Symfony and Symfony Bridge
  • Create a service
  • Create a test
<?php

namespace App\Tests;

// My service namespace here
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class ServiceTest extends WebTestCase
{
    /**
     * {@inheritdoc}
     */
    public function setUp(): void
    {
        self::bootKernel();
    }

    public function test(): void
    {
        self::$container->get(Service::class);
    }
}
  • Run ./bin/phpunit --stop-on-failure
  • Output
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: The "CLASS service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.

Additional context
File: vendor/symfony/framework-bundle/Test/TestContainer
Method: get

dump($this->getPrivateContainer()->has($id)); // False
dump($this->getPublicContainer()->has($id)); // False
dump($this->getRemovedIds()); // There is my service

Many thanks for your time,
Lelle

@lelledev lelledev changed the title Impossible to get private service from TestContainer Impossible to get private services from TestContainer Feb 7, 2019
@nicolas-grekas
Copy link
Member

The "CLASS service or alias has been removed or inlined when the container was compiled

What the error says is accurate.

If you want to test an unused service, you need to create a public test alias for it:
in config_test.yaml:

services:
    test.CLASS:
        alias: CLASS
        public: true

Closing as this is expected behavior, thus no bug to keep track of.

@lelledev
Copy link
Author

Hi @nicolas-grekas,

thank you for your quick response.
Sorry, I still not get it.
From this blog post (https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing) I should be able to get private services from the special container $container = self::$container; without replicate the declaration of the service for the test env.

Thanks,
Lelle

@flackovic
Copy link
flackovic commented Feb 14, 2019

@lelledaniele The thing is, service is not used anywhere in the project, so "RemoveUnusedDefinitionsPass" removes it from container.
Try to inject it in some of your controllers, just so Symfony think it is used, and then it should work.

I am not sure why does it behave like that in test container, since it is making TDD approach difficult.

@nicolas-grekas are there any plans to change this behaviour in test container, like private / public was changed here ?

@nicolas-grekas
Copy link
Member

Nope, no plans to do so, RemoveUnusedDefinitionsPass is absolutely required, keeping unused services would create a wide range of failure cases.

@flackovic
Copy link

@nicolas-grekas I see. Thanks for clarifying.

@lelledev
Copy link
Author

Thank you, both.

@mmenozzi
Copy link
Contributor

Nope, no plans to do so, RemoveUnusedDefinitionsPass is absolutely required, keeping unused services would create a wide range of failure cases.

I think that this should be documented here https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing

This because is pretty common that someone uses a service for the first time only in an integration test which tests its behavior.

@nicolas-grekas
Copy link
Member

@mmenozzi would you mind sending a PR to the doc repo?

@mmenozzi
Copy link
Contributor
mmenozzi 8000 commented Nov 13, 2019

Hi @nicolas-grekas I'd be happy but I don't know where to submit the PR. Is that blog post on the https://github.com/symfony/symfony-docs repo? If so could you point me to the correct file?

@javiereguiluz
Copy link
Member

@mmenozzi that's correct! According to our supported versions, this change must be done in 4.3 branch (and we'll later merge it in 4.4 and master too). Specifically, I guess you need to update the section about testing + container in this file: https://github.com/symfony/symfony-docs/blob/4.3/testing.rst Thanks!

@mmenozzi
Copy link
Contributor

Ok @javiereguiluz I'll do it asap.

@mmenozzi
Copy link
Contributor

Hi guys, I did the PR symfony/symfony-docs#12647 but I also think that the blog post https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing should be updated as well. That blog post is well indexed on Google. If I search for "symfony access private service in test" that post is the first result.

@javiereguiluz
Copy link
Member

@mmenozzi good idea! I've just updated the blog post.

javiereguiluz added a commit to symfony/symfony-docs that referenced this issue Apr 3, 2020
…doc (mmenozzi, weaverryan)

This PR was submitted for the master branch but it was merged into the 4.4 branch instead (closes #12647).

Discussion
----------

Add tip about accessing removed services in the testing doc

As requested [here](symfony/symfony#30104 (comment)) this commit will add a tip about accessing removed services through the special test container in the testing docs.

Commits
-------

f038841 clarifying how to create a public alias for a test
67dd3c1 Add tip about accessing removed services in the testing doc
javiereguiluz added a commit to symfony/symfony-docs that referenced this issue Jan 15, 2021
This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

Add warning about removed services

I was confused by the fact that the documentation explains:

> Finally, for the most rare edge-cases, Symfony includes a special container which provides access to all services, public and private. This special container is a service that can be get via the normal container

and the fact that the special container doesn't give access to the removed service.

So I added a tip in the documentation, taking inspiration from a Symfony article:

> Keep in mind that, because of how Symfony's service container work, unused services are removed from the container. This means that if you have a private service not used by any other service, Symfony will remove it and you won't be able to get it as explained in this article. The solution is to define the service as public explicitly so Symfony doesn't remove it.

Source: https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing

This is also consistent with the error message from Symfony: https://github.com/symfony/symfony/blob/3ffe5573e9dd045e157c6f17358c700fceae3feb/src/Symfony/Component/DependencyInjection/Container.php#L275

See also #12647 and symfony/symfony#30104

Commits
-------

e6a6c33 Add warning about removed services
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
0