Skip to content
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

Double container instances is causing an overhead #586

Open
gmponos opened this issue Dec 4, 2017 · 6 comments
Open

Double container instances is causing an overhead #586

gmponos opened this issue Dec 4, 2017 · 6 comments

Comments

@gmponos
Copy link

gmponos commented Dec 4, 2017

Hello there,

According to symfony official documentation in order to test a controller you have to initialize a client like this:

        $client = static::createClient();

And this is what I've been doing.

after creating my client I used to do something like this:

        $this->loadFixtures($this->getFixtureData());

Then today I reached my memory limit and dived little deeper into this bundle. I realized that the reason was that there is a container loaded in $client = static::createClient(); and also loadFixtures is loading a second container.

After making some copy-paste custom code I changed the signature of loadFixtures to accept a container and the memory for PHP 5 dropped from ~500 MB to ~200 MB.

In my belief it would've been better if you let the developer set his own container somehow.

You could say that I could use the makeClient instead but unfortunately make client is doing the same thing and it loading a second container too by calling internally this

$client = static::createClient(array('environment' => $this->environment), $params)

Is there any workaround about this?

@gmponos gmponos changed the title Duplicate container instances Double container instances is causing an overhead Dec 4, 2017
@Jean85
Copy link
Contributor

Jean85 commented Dec 22, 2017

The fact that the client is loading a second container is absolutely correct. You don't want to use the same one, since the first one is spun up by the test and it's already booted, and it can be tainted by any modification or operation that you're doing to prepare your test case.

@gmponos
Copy link
Author

gmponos commented Dec 22, 2017

The work around that I found was this:

    public function setUp()
    {
        parent::setUp();
        $this->client = static::createClient();
        $this->containers['|test'] = $this->client->getContainer();
        $this->loadFixtures($this->getFixtureData());
    }

    public function tearDown()
    {
        unset($this->containers);
        unset($this->client);
        parent::tearDown();
    }

I feel it's kinda dirty and developers can easily forget to do this. Unfortunately it seems that I will need to either fork the project or go with a custom solution because it's way costly.

@Jean85 do you suggest that the client should not load a container or that LiipBundle should not load a second one?

@Jean85
Copy link
Contributor

Jean85 commented Dec 22, 2017

Nope, I suggest neither. You shouldn't mix those two different container, they are intended to stay completely separate! You're trying to optimize something that you shouldn't. And believe me, I'm speaking from experience, I've tried to do the same in the past, obtaining only issues and unreliable tests.

The system under test need it's own container, and it's inside the client.
You (may) need a container inside the tests, to manipulate the state of your app before the test, or to make assertions after, but you have to use a separate one.

@alexislefebvre alexislefebvre transferred this issue from liip/LiipFunctionalTestBundle Feb 19, 2021
@alexislefebvre alexislefebvre transferred this issue from liip/LiipTestFixturesBundle Jun 1, 2021
@gnat42
Copy link
Contributor

gnat42 commented Dec 16, 2021

@Jean85 is it possible to get the container inside the app? The reason being is we've successfully setup an application so that we've created a decorated service in the test environment, but we want to configure its responses based a scenario (this service is an API client so we don't want actual requests going to the network). Is it possible to get access to that mock service from the app to say, when you see this request, respond with this data?

@Jean85
Copy link
Contributor

Jean85 commented Dec 16, 2021

With Symfony 5.3 and further, the container of the client is the same that you get from the new getContainer native method, so if you rely on that (and not the one from this package) you can do it.

Otherwise, you could always call getContainer on the client itself... But if the service gets instantiated again due to a kernel reboot you would be out of luck.

That's why I circumvent these kind of stuff with static calls generally...

@gnat42
Copy link
Contributor

gnat42 commented Dec 16, 2021

Thanks @Jean85 yeah we couldn't figure out how to get the container from the client reliably. I went the same way and just put some public static methods on the mock service so that its 'configurable' and that did the trick as well.

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

3 participants