test: 补齐关键路径交互式集成测试
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import ElementPlus, { ElMessage } from 'element-plus'
|
||||
import Login from '@/components/Login.vue'
|
||||
import router from '@/router'
|
||||
import { login } from '@/api/login'
|
||||
|
||||
vi.mock('@/api/login', () => ({
|
||||
login: vi.fn(),
|
||||
logout: vi.fn(),
|
||||
}))
|
||||
|
||||
/**
|
||||
* 交互式集成测试:真实挂载 Login,通过 setValue / trigger('click') 模拟用户行为,
|
||||
* 断言提交链路(凭证传递、成功/失败分支、localStorage 与路由结果)。
|
||||
*
|
||||
* 注意:jsdom 下 Element Plus 的 callback 式表单校验不可靠(空表单也可能判有效),
|
||||
* “空账号被校验拦截”这类行为由 e2e/login.spec 在真实浏览器中覆盖,此处不重复断言。
|
||||
*/
|
||||
describe('Login 交互流程(集成)', () => {
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks()
|
||||
localStorage.clear()
|
||||
await router.push('/login')
|
||||
await router.isReady()
|
||||
})
|
||||
|
||||
const mountLogin = async () => {
|
||||
const wrapper = mount(Login, {
|
||||
global: { plugins: [ElementPlus, router] },
|
||||
})
|
||||
await flushPromises()
|
||||
return wrapper
|
||||
}
|
||||
|
||||
const findSubmitButton = (wrapper: ReturnType<typeof mount> extends Promise<infer T> ? T : never) =>
|
||||
wrapper.findAll('button').find((b) => b.text().includes('进入系统'))!
|
||||
|
||||
it('填写账号密码后点击“进入系统”,提交凭证并跳转 /welcome', async () => {
|
||||
vi.mocked(login).mockResolvedValue({ code: 200, message: '登录成功' } as any)
|
||||
const wrapper = await mountLogin()
|
||||
|
||||
await wrapper.find('input[placeholder="请输入账号"]').setValue('admin')
|
||||
await wrapper.find('input[placeholder="请输入密码"]').setValue('123456')
|
||||
await findSubmitButton(wrapper).trigger('click')
|
||||
// /welcome 是懒加载路由,动态 import 需要宏任务,用 waitFor 轮询等待到达
|
||||
await vi.waitFor(() => expect(router.currentRoute.value.path).toBe('/welcome'))
|
||||
|
||||
expect(login).toHaveBeenCalledWith('admin', '123456')
|
||||
expect(localStorage.getItem('isLoggedIn')).toBe('true')
|
||||
expect(ElMessage.success).toHaveBeenCalledWith('登录成功')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('后端返回失败时提示错误、不写登录标记、不跳转', async () => {
|
||||
vi.mocked(login).mockResolvedValue({ code: 500, message: '账号或密码错误' } as any)
|
||||
const wrapper = await mountLogin()
|
||||
|
||||
await wrapper.find('input[placeholder="请输入账号"]').setValue('admin')
|
||||
await wrapper.find('input[placeholder="请输入密码"]').setValue('wrong-pass')
|
||||
await findSubmitButton(wrapper).trigger('click')
|
||||
await flushPromises()
|
||||
await flushPromises()
|
||||
|
||||
expect(login).toHaveBeenCalledWith('admin', 'wrong-pass')
|
||||
expect(ElMessage.error).toHaveBeenCalledWith('账号或密码错误')
|
||||
expect(localStorage.getItem('isLoggedIn')).toBeNull()
|
||||
expect(router.currentRoute.value.path).toBe('/login')
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user