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

Vue测试新手求助:Axios调用真实Laravel Sanctum服务器的集成测试问题

嘿,我刚好处理过类似的 Laravel Sanctum + Vue 集成测试场景,给你分享下可行的解决方案:

解决方案:Laravel Sanctum + Vue 真实API集成测试

针对你遇到的两个核心问题,分步骤拆解处理:


测试环境(Node.js)里的 Axios 不会像浏览器那样自动管理 Cookie,所以需要借助工具模拟浏览器的 Cookie 存储机制:

步骤1:安装依赖

安装专门处理 Cookie 的工具包:

npm install axios-cookiejar-support tough-cookie --save-dev

步骤2:配置 Axios 实例使用 CookieJar

修改你的 authApi 配置,让它绑定 CookieJar 来自动存储和携带 Cookie:

import axios from 'axios';
import { wrapper } from 'axios-cookiejar-support';
import { CookieJar } from 'tough-cookie';

// 初始化 CookieJar,模拟浏览器的 Cookie 存储
const cookieJar = new CookieJar();
// 用 wrapper 包装 Axios 实例,让它支持 CookieJar
const authApi = wrapper(axios.create({
  baseURL: 'http://testing.backend.vipany.test/api/auth',
  withCredentials: true,
  jar: cookieJar // 绑定 CookieJar
}));

export default authApi;

步骤3:验证 CSRF Token 存储

调用 /sanctum/csrf-cookie 后,Token 会自动存在 CookieJar 里,Axios 后续请求会自动把这个 Token 放到 X-XSRF-TOKEN 请求头中,不需要手动提取。你可以在测试里验证:

it('stores CSRF token in cookie jar', async function() {
  this.timeout(5000);
  await authApi.get('/sanctum/csrf-cookie');
  
  // 从 CookieJar 中读取已存储的 Token
  const cookies = await authApi.jar.getCookies('http://testing.backend.vipany.test');
  const xsrfToken = cookies.find(cookie => cookie.key === 'XSRF-TOKEN');
  
  expect(xsrfToken).to.exist;
});

为什么你之前手动读取 response.config.headers['X-XSRF-TOKEN'] 会返回 undefined?因为 /sanctum/csrf-cookie 接口返回的是 204 状态,响应头里不会携带 Token,Token 是直接存在 Set-Cookie 响应头里,由 CookieJar 自动存储的。


2. Vue 组件内 Axios 请求的等待问题(替代 done())

Mocha 原生支持 async/await,完全可以替代 done() 来处理异步逻辑,针对组件内的请求,有两种可靠的等待方式:

方式1:等待组件数据更新

如果组件在请求完成后会更新 data 里的状态(比如 userInfo),可以循环等待直到数据就绪:

import { mount } from '@vue/test-utils';
import UserProfile from '../../src/components/UserProfile.vue';
import authApi from '../../src/components/connections/auth';

describe('UserProfile Component', () => {
  it('loads user data via real API', async function() {
    this.timeout(10000); // 真实API可能较慢,延长超时时间
    
    // 先获取 CSRF Token,确保后续请求合法
    await authApi.get('/sanctum/csrf-cookie');
    // 假设先登录(根据你的业务流程调整)
    await authApi.post('/login', { email: 'test@example.com', password: 'password' });
    
    const wrapper = mount(UserProfile);
    
    // 循环等待直到组件数据更新
    while (!wrapper.vm.userInfo) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
    
    // 断言组件渲染了正确的用户信息
    expect(wrapper.find('.user-email').text()).to.equal('test@example.com');
  });
});

方式2:用 Axios 拦截器跟踪请求状态

如果组件内的请求没有直接关联到可观测的 data,可以给 Axios 添加拦截器,标记请求完成状态:

import { mount } from '@vue/test-utils';
import YourComponent from '../../src/components/YourComponent.vue';
import authApi from '../../src/components/connections/auth';

describe('YourComponent', () => {
  let requestCompleted = false;

  beforeEach(() => {
    // 重置状态
    requestCompleted = false;
    // 添加响应拦截器,标记请求完成
    authApi.interceptors.response.use(
      (response) => {
        requestCompleted = true;
        return response;
      },
      (error) => {
        requestCompleted = true;
        return Promise.reject(error);
      }
    );
  });

  it('completes real API request on button click', async function() {
    this.timeout(10000);
    await authApi.get('/sanctum/csrf-cookie');
    
    const wrapper = mount(YourComponent);
    // 触发组件内的请求(比如点击按钮)
    wrapper.find('.fetch-data-btn').trigger('click');
    
    // 等待请求完成
    while (!requestCompleted) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
    
    // 断言组件的变化
    expect(wrapper.find('.data-result').exists()).to.be.true;
  });
});

关键总结

  1. 用 axios-cookiejar-support + tough-cookie 模拟浏览器的 Cookie 管理,解决 Sanctum 的认证问题
  2. 用 Mocha 的 async/await 替代 done(),配合循环等待或拦截器跟踪组件内的异步请求
  3. 测试前务必先获取 CSRF Token,确保后续请求通过 Sanctum 的认证校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:37:41