登录组件测试前置工具(loginTestUtils.js)
用于在组件测试前完成真实登录流程,获取有效 token 和用户信息,为后续依赖登录状态的测试提供前置环境。
javascript
import { mount } from "@vue/test-utils";
import Vue from "vue";
import Vuex from "vuex";
import Login from "@/views/login.vue"; // 登录组件
import flushPromises from "flush-promises";
import * as loginApi from "@/api/login"; // 使用真实登录接口
import { setToken } from "@/utils/auth"; // 导入 token 存储工具(mock 或真实)
import MOCK_USER from "./mockuser"; // 登录测试用账号
// 注册 Vuex
Vue.use(Vuex);
/**
* 创建包含登录状态的 Vuex Store
* @returns {Vuex.Store} 初始化的 Store 实例
*/
const createStore = () => {
return new Vuex.Store({
state: {
token: "", // 初始为空
user: null,
},
mutations: {
// 同步更新 token(需与项目中保持一致)
SET_TOKEN(state, token) {
state.token = token;
},
// 同步更新用户信息
SET_USER(state, user) {
state.user = user;
},
},
actions: {
// 真实登录逻辑(复用项目登录 action)
Login: async ({ commit }, loginForm) => {
const response = await loginApi.login(loginForm); // 调用真实登录接口
const { token, userInfo } = response.data;
commit("SET_TOKEN", token);
commit("SET_USER", userInfo);
return response.data;
},
},
});
};
/**
* 模拟用户登录流程(真实接口调用)
* @param {Object} credentials - 登录凭证(默认使用 MOCK_USER)
* @returns {Object} 登录结果(包含 token、user、store 等)
* @throws {Error} 登录失败时抛出错误
*/
export async function mockLogin(credentials = MOCK_USER) {
// 1. 初始化 Store
const store = createStore();
// 2. 挂载登录组件
const loginWrapper = mount(Login, {
Vue,
store, // 注入 Store,确保组件内可访问 this.$store
mocks: {
$router: { push: jest.fn() }, // 模拟路由跳转(避免真实导航)
},
});
// 3. 输入登录信息
await loginWrapper
.find(".login-form .el-form-item:nth-of-type(1) input")
.setValue(credentials.phoneNumber);
await loginWrapper
.find(".login-form .el-form-item:nth-of-type(2) input")
.setValue(credentials.code);
// 4. 触发登录按钮点击
await loginWrapper.find(".login-btn").trigger("click");
// 5. 等待接口响应与状态更新(最多等待 10 秒)
let waitCount = 0;
while (waitCount < 100) {
// 100 * 100ms = 10s 超时
await new Promise((resolve) => setTimeout(resolve, 100));
waitCount++;
}
await flushPromises(); // 等待所有异步操作完成
await loginWrapper.vm.$nextTick(); // 等待 DOM 更新
// 6. 验证登录结果
const token = store.state.token;
if (!token) {
throw new Error("登录失败:未获取到 token,请检查接口或凭证");
}
// 7. 存储 token 供后续请求使用
setToken(token);
// 8. 返回登录状态
return {
token, // 真实接口返回的 token
user: store.state.user, // 真实用户信息
loginWrapper, // 登录组件 Wrapper 实例
store, // 包含登录状态的 Store 实例
};
}核心功能说明:
- 真实登录流程:调用项目真实登录接口,模拟用户输入和点击行为,获取有效 token。
- 状态管理:通过 Vuex Store 管理登录状态(token 和用户信息),与项目实际逻辑一致。
- 前置依赖准备:登录成功后自动存储 token,为后续依赖登录状态的组件测试(如个人中心、订单页)提供环境。
- 超时控制:避免接口长时间无响应导致测试卡死,最长等待 10 秒。
使用场景:
在需要登录状态的组件测试文件中引入:
javascript
import { mockLogin } from "./loginTestUtils";
// 在测试用例执行前完成登录
beforeAll(async () => {
const { token, store } = await mockLogin();
// 将 store 传入后续组件的挂载参数中
});