Vue测试新手求助:Axios调用真实Laravel Sanctum服务器的集成测试问题
嘿,我刚好处理过类似的 Laravel Sanctum + Vue 集成测试场景,给你分享下可行的解决方案:
解决方案:Laravel Sanctum + Vue 真实API集成测试
针对你遇到的两个核心问题,分步骤拆解处理:
1. 手动处理 CSRF Token 和会话 Cookie
测试环境(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; }); });
关键总结
- 用
axios-cookiejar-support+tough-cookie模拟浏览器的 Cookie 管理,解决 Sanctum 的认证问题 - 用 Mocha 的
async/await替代done(),配合循环等待或拦截器跟踪组件内的异步请求 - 测试前务必先获取 CSRF Token,确保后续请求通过 Sanctum 的认证校验
内容的提问来源于stack exchange,提问作者ndberg
相关产品推荐
相关产品推荐

