Skip to content

Commit

Permalink
[Testing] Create a section dedicated to sending multiple requests in …
Browse files Browse the repository at this point in the history
…one functional test
  • Loading branch information
MatTheCat committed Sep 6, 2023
1 parent 597a955 commit b665b5e
Showing 1 changed file with 51 additions and 8 deletions.
59 changes: 51 additions & 8 deletions testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -619,15 +619,58 @@ This allows you to create all types of requests you can think of:
:ref:`framework.test <reference-framework-test>` option is enabled).
This means you can override the service entirely if you need to.

.. caution::
Multiple requests in one test
.............................

After you send one request, subsequent ones will make the client reboot
the kernel, recreating the container from scratch.
This ensures that requests are "isolated" using "new" service objects,
but can cause some unexpected behaviors. For example, the security token will
be cleared, Doctrine entities will be "detached"…

Calling the client's
:method:`Symfony\\Bundle\\FrameworkBundle\\KernelBrowser::disableReboot`
method is the first step to work around this, as this will reset the kernel
instead of rebooting it. Now, resetting the kernel will call the reset method
of every ``kernel.reset`` tagged service, which will **also** clear the
security token, detach entities and so on.

As such, the next step is to create a
:doc:`compiler pass </service_container/compiler_passes>` to remove the
``kernel.reset`` tag from these services in your test environment::

// src/Kernel.php
namespace App;

use App\DependencyInjection\Compiler\CustomPass;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
use MicroKernelTrait;

// …

Before each request, the client reboots the kernel, recreating
the container from scratch.
This ensures that every requests are "isolated" using "new" service objects.
Also, it means that entities loaded by Doctrine repositories will
be "detached", so they will need to be refreshed by the manager or
queried again from a repository.
You can disable this behavior by calling the :method:`disableReboot() <Symfony\\Bundle\\FrameworkBundle\\KernelBrowser::disableReboot>` method.
protected function build(ContainerBuilder $container): void
{
if ('test' === $this->environment) {
$container->addCompilerPass(new class() implements CompilerPassInterface {
public function process(ContainerBuilder $container): void
{
// prevents the security token to be cleared
$container->getDefinition('security.token_storage')->clearTag('kernel.reset');

// prevents entities to be detached
$container->getDefinition('doctrine')->clearTag('kernel.reset');

// …
}
});
}
}
}

Browsing the Site
.................
Expand Down

0 comments on commit b665b5e

Please sign in to comment.