You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony3.4开启logout_on_user_change时单元测试登录失败问题

解决Symfony 4中logout_on_user_change导致单元测试登录失败的问题

我之前也碰到过一模一样的问题:把logout_on_user_change设为true(Symfony 4默认就是这个配置)后,开发环境里登录、登出啥的都正常,但跑单元测试的时候,登录认证总是失败,折腾了好一阵才找到根源——后台的用户操作触发了这个自动登出机制,而问题出在用户实体的serialize()和isEqualTo()方法的字段不匹配上。

问题原因

当logout_on_user_change开启时,Symfony会在每次请求时对比会话中序列化的用户数据,和从数据库加载的用户对象是否一致。如果isEqualTo()方法校验的字段,和serialize()里序列化的字段不一样,就会被判定为用户信息变更,触发自动登出,这在单元测试场景下就会导致认证失败。

解决方案

核心就是确保isEqualTo()方法里校验的所有字段,和serialize()函数中序列化的字段完全一致,不能有遗漏也不能多出来。下面是我调整后的正确代码示例:

/**
 * @see \Serializable::serialize()
 */
public function serialize()
{
    return serialize(
        array(
            $this->id,
            $this->email,
            $this->password,
            $this->salt
        )
    );
}

/**
 * @see \Serializable::unserialize()
 */
public function unserialize($serialized)
{
    list (
        $this->id,
        $this->email,
        $this->password,
        $this->salt
    ) = unserialize($serialized, ['allowed_classes' => false]);
}

public function isEqualTo(UserInterface $user)
{
    if ($this->id !== $user->getId()) {
        return false;
    }

    if ($this->password !== $user->getPassword()) {
        return false;
    }

    if ($this->salt !== $user->getSalt()) {
        return false;
    }

    if ($this->email !== $user->getEmail()) {
        return false;
    }

    return true;
}

你可以看到,serialize()里序列化了id、email、password、salt这四个字段,对应的isEqualTo()也逐一校验了这四个字段,这样就能保证用户对象的一致性校验准确,不会在单元测试里误触发自动登出了。

内容的提问来源于stack exchange,提问作者Pointi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:40:24