@@ -579,15 +579,55 @@ This allows you to create all types of requests you can think of:
579
579
:ref: `framework.test <reference-framework-test >` option is enabled).
580
580
This means you can override the service entirely if you need to.
581
581
582
- .. caution ::
582
+ Multiple Requests in One Test
583
+ .............................
584
+
585
+ After making a request, subsequent requests will make the client reboot the kernel.
586
+ This recreates the container from scratch to ensures that requests are isolated
587
+ and use new service objects each time. This behavior can have some unexpected
588
+ consequences: for example, the security token will be cleared, Doctrine entities
589
+ will be detached, etc.
590
+
591
+ First, you can call the client's :method: `Symfony\\ Bundle\\ FrameworkBundle\\ KernelBrowser::disableReboot `
592
+ method to reset the kernel instead of rebooting it. In practice, Symfony
593
+ will call the ``reset() `` method of every service tagged with ``kernel.reset ``.
594
+ However, this will **also ** clear the security token, detach Doctrine entities, etc.
595
+
596
+ In order to solve this issue, create a :doc: `compiler pass </service_container/compiler_passes >`
597
+ to remove the ``kernel.reset `` tag from some services in your test environment::
583
598
584
- Before each request, the client reboots the kernel, recreating
585
- the container from scratch.
586
- This ensures that every requests are "isolated" using "new" service objects.
587
- Also, it means that entities loaded by Doctrine repositories will
588
- be "detached", so they will need to be refreshed by the manager or
589
- queried again from a repository.
590
- You can disable this behavior by calling the :method: `disableReboot() <Symfony\\ Bundle\\ FrameworkBundle\\ KernelBrowser::disableReboot> ` method.
599
+ // src/Kernel.php
600
+ namespace App;
601
+
602
+ use App\DependencyInjection\Compiler\CustomPass;
603
+ use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
604
+ use Symfony\Component\DependencyInjection\ContainerBuilder;
605
+ use Symfony\Component\HttpKernel\Kernel as BaseKernel;
606
+
607
+ class Kernel extends BaseKernel
608
+ {
609
+ use MicroKernelTrait;
610
+
611
+ // ...
612
+
613
+ protected function build(ContainerBuilder $container): void
614
+ {
615
+ if ('test' === $this->environment) {
616
+ $container->addCompilerPass(new class() implements CompilerPassInterface {
617
+ public function process(ContainerBuilder $container): void
618
+ {
619
+ // prevents the security token to be cleared
620
+ $container->getDefinition('security.token_storage')->clearTag('kernel.reset');
621
+
622
+ // prevents Doctrine entities to be detached
623
+ $container->getDefinition('doctrine')->clearTag('kernel.reset');
624
+
625
+ // ...
626
+ }
627
+ });
628
+ }
629
+ }
630
+ }
591
631
592
632
Browsing the Site
593
633
.................
0 commit comments