'How to change locale in Symfony5 / PHPUnit before calling request?

I need to change locale in my functional test:

<?php

namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class TranslationControllerTest extends WebTestCase
{
    public function testIndex()
    {

        $client = static::createClient();

        $client->request('GET', '/translation.js');
        $client->getRequest()->setLocale('en');

        $content = $client->getResponse()->getContent();
        $trans = json_decode(substr($content, strpos($content, "'{") + 1, strpos($content, "}'") - strpos($content, "'{")), true);

        $this->assertEquals(200, $client->getResponse()->getStatusCode());
        $this->assertSame($trans['test.case'], 'en');

    }
}

Seems that $client->getRequest()->setLocale('en'); not working properly. What is the correct way?



Solution 1:[1]

I have been searching for this also for quite some time. I now found out, that it can be derived from https://symfony.com/doc/current/session/locale_sticky_session.html:

class MyTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient();

        $session = self::$container->get(SessionInterface::class);
        $session->set('_locale', 'de');

        $client->request('GET', '/dashboard');
        // The resulting page is in German
        ....
    }
}

I am not sure if this is defined behavior, since changing the locale twice in a test behaves a bit strange:

class MyTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient();

        $session = self::$container->get(SessionInterface::class);
        $session->set('_locale', 'de');

        $client->request('GET', '/dashboard');
        // The resulting page is in English (my default locale)
        ....

        $session->set('_locale', 'nl');

        $client->request('GET', '/dashboard');
        // The resulting page is in German
        ....
    }
}

Solution 2:[2]

You have to "save" your session like this :

    $container = static::getContainer();
    /** @var SessionInterface $session */
    $session = $container->get('session');
    $session->set('_locale', 'de');
    $session->save();
    dump($session->get('_locale')); //de

    $session->set('_locale', 'en');
    $session->save();
    dump($session->get('_locale')); //en

From the source code :

Force the session to be saved and closed. This method is generally not required for real sessions as the session will be automatically saved at the end of code execution.

SessionInterface source code : https://github.com/symfony/symfony/blob/6.0/src/Symfony/Component/HttpFoundation/Session/SessionInterface.php

Common usage : https://symfony.com/doc/current/components/http_foundation/sessions.html

Cheers :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Luc Hamers
Solution 2 Mick3DIY