Laravel 6单元测试报错Session store not set on request如何解决?
问题根因
报错RuntimeException: Session store not set on request的核心原因是测试环境中请求实例没有绑定有效的session驱动,触发场景有三类:
- 涉及HTTP请求、认证、session操作的测试被放在了Unit测试目录下,Laravel单元测试默认不加载
web中间件组(包含StartSession等session初始化逻辑) - 测试代码中
withSession方法调用时机错误:该方法需要在发起请求前调用,你写在了请求得到响应后,对请求逻辑没有生效 - 目标路由未归属到
web中间件组,没有自动加载session驱动
排查步骤
- 检查测试文件所在目录:确认文件是否放在
tests/Feature目录下 - 检查
withSession调用顺序:确认该方法在post请求之前执行 - 检查路由配置:确认
/admin/login路由归属在web中间件组下 - 检查测试类配置:确认测试类没有主动关闭session中间件
解决方案
1. 调整测试文件归属
将HostLoginTest.php从tests/Unit目录移动到tests/Feature目录,Feature测试默认加载完整HTTP中间件栈,包含session初始化逻辑。
2. 修正测试代码逻辑
调整withSession调用顺序到请求发起前,修正后的测试代码如下:
public function testUserCanLoginCorrectCredentials() { $this->withoutExceptionHandling(); $user = factory(Users::class)->create(); // 发请求前设置session $this->withSession(['user_id' => $user->id]); $response = $this->post('/admin/login', [ 'email' => $user->email, 'password' => '123456789', ]); $response->assertRedirect('/admin/dashboard'); $this->assertAuthenticatedAs($user); }
3. 可选:单元测试下手动开启session
如果需要保留测试文件在Unit目录下,在测试类的setUp方法中添加session初始化逻辑即可:
protected function setUp(): void { parent::setUp(); // 手动启动session驱动 $this->app->make('session')->start(); }
4. 校验路由配置
确认登录路由归属web中间件组,示例配置如下:
Route::middleware('web')->group(function () { Route::post('/admin/login', [\App\Http\Controllers\Auth\LoginController::class, 'login']); // 其他后台相关路由 });
完成以上操作后重新运行测试即可解决报错。
内容的提问来源于stack exchange,提问作者SulaiMaan
相关产品推荐
相关产品推荐

