20260819173221

This commit is contained in:
oneao committed 2026-08-19 17:32:25 +08:00
1 parent 1ffc8e1ac9
commit a0a4273f4c
326 files changed
+301646 -2314

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
/**
* 测试 harness:为「页面/功能」组件测试提供统一装配。
*
* 设计原则:
* - 所有请求都收敛在 @/services/api,测试时只需 vi.mock('@/services/api') 即可确定性驱动状态。
* - pinia 带 persist 插件(与生产一致),避免 stores 在测试里行为漂移。
* - 用 memory history 路由,避免真实 History API 副作用。
* - 子组件默认 shallowMount 打桩,页面测试只关注「页面自身逻辑」:把子组件事件 emit 出来即可。
*
* 用法见 tests/views/*.spec.js
*/
import { shallowMount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import { createRouter, createMemoryHistory } from 'vue-router'
/**
* 创建一个带 persist 插件的全新 pinia,并设为 active(便于测试里直接 useXStore())。
*
* 注意:pinia 4 的 `pinia.use()` 在实例未安装到 app 前只把插件放入 toBeInstalled 队列,
* 必须经过 `install(app)` 才会真正注册。页面测试经 @vue/test-utils 的 plugins 挂载会自动 install,
* 但"纯 store 层测试"(setActivePinia + useXStore)不会,导致 persist 插件静默失效、
* store 上缺少 $hydrate/$persist。这里用一个假 app 触发 install,保证两类测试行为一致。
*/
export function createTestPinia() {
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
pinia.install({ provide() {}, config: { globalProperties: {} } })
setActivePinia(pinia)
return pinia
}
/** 创建一个 memory history 路由,并可预先定位到某个 location(含 query) */
export function createTestRouter(initialLocation = '/') {
const router = createRouter({
history: createMemoryHistory(),
routes: [
{ path: '/:pathMatch(.*)*', name: 'catch-all', component: { template: '<div />' } },
],
})
router.push(initialLocation)
return router
}
/**
* 挂载一个页面/功能组件。
* @param {object} Component 组件定义(通常 import 自 @/views/...)
* @param {object} [options]
* @param {string} [options.location] 初始路由 location,如 '/login?redirect=/dashboard'
* @param {object} [options.stubs] 额外子组件打桩(覆盖 shallowMount 默认打桩)
* @param {object} [options.global] 透传给 @vue/test-utils 的 global 选项
* @param {object} [options.mountOptions] 透传其余 mount 选项
* @returns {Promise<{ wrapper, router, pinia }>}
*/
export async function mountPage(Component, options = {}) {
const pinia = createTestPinia()
const router = createTestRouter(options.location || '/')
await router.isReady()
const wrapper = shallowMount(Component, {
global: {
plugins: [pinia, router],
stubs: options.stubs || {},
...(options.global || {}),
},
...(options.mountOptions || {}),
})
return { wrapper, router, pinia }
}