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

ApiTestCase can lead to several kernels (and therefore several entity managers and so on) #6516

Open
Niolak opened this issue Aug 14, 2024 · 0 comments

Comments

@Niolak
Copy link

Niolak commented Aug 14, 2024

API Platform version(s) affected: 3.2.14

Description
ApiTestCase::createClient always creates a new kernel. If you need services in your test to create the context with static::getContainer()->get(MyService::class);, two kernels will be created, which leads to several entity managers.

How to reproduce

class TransmissionActionTest extends ApiTestCase
{
    public function testSomething(): void
    {
      $myService = static::getContainer()->get(MyService::class); // Here, the kernel is booted via getContainer
      $myService->createAContextForTheTest();
      
      $response = static::createClient()->request('POST', '/my-action'); // Here, a 2nd kernel is created
      
      // example of what could go wrong next
      $myRepo = static::getContainer()->get(MyResourceRepository::class);
      $resourceCreatedByTheAction = $myRepo->findOneBy(['created-by-my-action' => true]); // not the same entitymanager as the one used by the request
      $this->assertNotNull($resourceCreatedByTheAction); // failure
    }
}

(I've simplified the example for readability: I'm not sure that findOneBy would return null on such a simple example. The fact remains that the wrong entitymanager is used, which can be a problem in some cases.)

Possible Solution
In ApiTestCase::createClient(), create the kernel only if not booted.
Replace

$kernel = static::bootKernel($kernelOptions);

by

$kernel = static::$booted ? static::$kernel : static::bootKernel($kernelOptions);

I even think that createClient should not create the kernel (dependency injection principle) but then the change would be a breaking change.

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

1 participant