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

Laravel SSO集成测试遇NotFoundHttpException,寻求联合测试方案

解决Laravel集成测试与外部SSO联合测试的问题

你遇到的核心问题是:Laravel的集成测试工具(比如$this->visit())默认只会解析本地应用的路由,当你修改app.url指向SSO的地址后,它还是会尝试在本地项目的路由列表里找/login,而这个路由属于外部SSO系统,自然会抛出NotFoundHttpException。

下面是几种可行的联合测试方案,你可以根据测试场景选择:

方案一:Mock SSO服务(推荐用于单元/集成测试)

如果你的测试重点是验证本地项目与SSO的交互逻辑,而不是测试SSO本身的功能,最好的方式是用Laravel的HTTP客户端模拟SSO的所有响应,这样不需要依赖外部服务,测试速度也更快。

示例代码:

public function testLoginWithMockedSSO()
{
    // 模拟SSO的关键接口响应
    Http::fake([
        // 匹配SSO的登录页面请求
        '192.168.33.11:8081/login*' => Http::response('<html><form action="/login/submit" method="post"></form></html>', 200),
        // 模拟登录提交后的重定向(跳回本地项目的回调地址)
        '192.168.33.11:8081/login/submit' => Http::redirect('http://your-local-app.test/sso/callback?token=mock-valid-token'),
        // 模拟SSO的用户信息接口,根据返回的token返回用户数据
        '192.168.33.11:8081/api/user' => Http::response([
            'id' => 1,
            'name' => 'Jasurbek',
            'email' => 'test@example.com'
        ], 200),
    ]);

    // 访问本地项目的登录入口(它应该自动跳转到SSO)
    $response = $this->get('/login?service_id=2');
    
    // 断言成功跳转到SSO的登录页面
    $response->assertRedirect('http://192.168.33.11:8081/login?service_id=2');

    // 模拟SSO登录完成后的回调请求
    $response = $this->get('/sso/callback?token=mock-valid-token');

    // 断言用户成功登录并跳转到指定页面
    $response->assertRedirect('/dashboard');
    $this->assertAuthenticated();
}

方案二:直接测试SSO回调逻辑

如果你的测试目标是验证本地项目处理SSO回调的正确性,可以跳过SSO登录页面的交互,直接构造回调请求传入模拟的合法参数:

public function testSSOCallbackHandlesValidToken()
{
    // 模拟SSO返回的用户信息
    $mockUser = [
        'id' => 1,
        'name' => 'Jasurbek',
        'email' => 'test@example.com'
    ];

    // 拦截SSO的用户信息查询请求,返回模拟数据
    Http::fake([
        '192.168.33.11:8081/api/user' => Http::response($mockUser, 200),
    ]);

    // 直接访问本地项目的SSO回调路由,传入模拟的token
    $response = $this->get('/sso/callback?token=mock-valid-token');

    // 断言用户被正确创建/登录,并且跳转到首页
    $response->assertRedirect('/dashboard');
    $this->assertDatabaseHas('users', [
        'email' => 'test@example.com'
    ]);
    $this->assertAuthenticatedAs(User::whereEmail('test@example.com')->first());
}

方案三:端到端测试(用于完整流程验证)

如果你需要测试从本地项目跳转到SSO、登录、再跳回本地的完整流程,就需要用到浏览器自动化工具(比如Playwright、Selenium),这类工具可以真正在浏览器中跨端口/域名跳转。

以Laravel Playwright包为例,示例代码:

public function testFullLoginFlowWithRealSSO()
{
    // 启动浏览器访问本地项目的登录页
    $this->browser->visit('/login?service_id=2');

    // 等待页面跳转到SSO的登录页面(8081端口)
    $this->browser->waitForUrl('http://192.168.33.11:8081/login?service_id=2');

    // 在SSO页面填写登录信息
    $this->browser->fill('input[name="name"]', 'your-sso-username');
    $this->browser->fill('input[name="password"]', 'your-sso-password');
    $this->browser->click('button[type="submit"]');

    // 等待页面跳转回本地项目的首页
    $this->browser->waitForUrl('http://your-local-app.test/dashboard');

    // 断言登录成功,页面显示用户名
    $this->browser->assertSee('Welcome, Jasurbek');
}

关键提醒

  • 不要直接修改app.url来指向SSO,这个配置是给本地Laravel应用用的,修改后会导致测试工具混淆路由归属。
  • 集成测试重点验证本地逻辑,Mock外部服务是最佳实践;端到端测试验证完整流程,但依赖外部服务的可用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:30:53