使用loginUser()进行Symfony单元测试,登录不起作用(返回302到登录页面)

问题描述 投票:0回答:2

我正在为 Symfony 5.4 应用程序构建测试。

我创建了一个这样的测试:

public function testCreateProduct() {
    $client = static::createClient();
    /** @var User $mainAdmin */
    $mainAdmin = static::getContainer()->get(UserRepository::class)->find(1);

    //$client->catchExceptions(false);
    $client->loginUser($mainAdmin);

    $crawler = $client->request('GET', '/en/product/new');

    $this->assertResponseIsSuccessful();
    $this->assertSelectorTextContains('span.username', $mainAdmin->getUsername());

}

但是登录不起作用,我收到 302 重定向到登录页面,如果我设置

catchExceptions(false)
,我会收到
AccessDeniedException

我该如何调试这个?


编辑: 我尝试将补丁更改为公共路线,然后我做了一个

dd($this->getUser(), $request)

getUser()
为空,但请求会话包含用户:

#session: Symfony\Component\HttpFoundation\Session\Session {#16616
#storage: Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage {#16631
  -savePath: "C:\www\project\var\cache\test/sessions"
  #id: "a9d00704e1a0211d06ebddadfaabbf0188e9d65d94faac05afbdc63bb9fb7caa"
  #name: "MOCKSESSID"
  #started: true
  #closed: false
  #data: array:3 [
    "_sf2_attributes" => &1 array:1 [
      "_security_main" => "O:52:"Symfony\Bundle\FrameworkBundle\Test\TestBrowserToken":2:{i:0;s:4:"main";i:1;a:5:{i:0;C:15:"App\Entity\User":118:{a:5:{i:0;i:2;i:1;s:5:"admin";i:2;s:60:"$2y$13$abcdefghi......";i:3;i:1;i:4;b:0;}}i:1;b:1;i:2;N;i:3;a:0:{}i:4;a:9:{i:0;s:9:"ROLE_USER";i:1;s:10:"ROLE_ADMIN";i:2;[...]}}}"
    ]
    "_sf2_meta" => &2 array:3 [
      "u" => 1645718565
      "c" => 1645718565
      "l" => 0
    ]
    "_symfony_flashes" => &3 []
  ]

我看到了两者之间的区别

$request->getSession()->getBag('attributes')
在开发(工作)与测试中完成:在开发中我有
_security_secured_area
,而在测试中我有
_security_main
。可能是这个原因?

php unit-testing symfony symfony5
2个回答
4
投票

解决了。

由于我在

security.yaml
中使用了自定义防火墙名称,在我的例子中
secured_area
,我必须将其作为
loginUser()
的第二个参数传递:

$client->loginUser($mainAdmin, 'secured_area');

0
投票

是的,像这样使用

secured_area

$client->loginUser($mainAdmin, 'secured_area');//call context

将像这样依赖

config/package/security.config

firewalls:
    main:
        name: secured_area

而且,这将调用(我在 symfony 7 下)一个像你的数据库一样的新数据库(称为“db”),添加“_test”:“db_test。

而且,这将忽略 .env.local,所以我必须让连接到 .env 中的 te 数据库,而这会调用 postgree (默认连接)。

如果我将上下文名称(以及连接的登录方式,也可以是带有入口点的custom_identificator)放在开发部分中,则不起作用。

如果我做到了这一切,那就对我有用。 如果您知道如何简化这一切,欢迎回答。

© www.soinside.com 2019 - 2024. All rights reserved.