React+Vitest登录表单单元测试:登录成功跳转验证失败
登录成功跳转测试失败的解决方案
问题分析
测试中登录成功后未触发跳转,找不到Profile页面元素,核心原因大概率是真实API请求未Mock、路由跳转验证方式不对,或者元素匹配条件过严。
具体修复步骤
1. Mock登录API,隔离外部依赖
单元测试不能依赖真实网络请求,用Vitest的vi.mock模拟dummyjson的登录成功响应:
// 测试文件顶部引入并Mockaxios import axios from 'axios'; vi.mock('axios'); // 成功测试用例中添加Mock逻辑 test('Valid username, password: ', async () => { // 模拟登录成功返回的数据 axios.post.mockResolvedValue({ data: { token: 'fake-test-token', user: { username: 'kminchelle' } } }); renderLoginPage(); const emailInput = screen.getByLabelText('username:'); const passwordInput = screen.getByLabelText('Password:'); const submitButton = screen.getByRole('button', { name: /login/i }); // 用user-event模拟真实用户输入(比fireEvent更贴近实际行为) await userEvent.type(emailInput, 'kminchelle'); await userEvent.type(passwordInput, '0lelplR'); await userEvent.click(submitButton); // 先验证API是否被正确调用 expect(axios.post).toHaveBeenCalledWith('https://dummyjson.com/auth/login', { username: 'kminchelle', password: '0lelplR' }); // 后续验证路由或页面元素 });
2. 换方式验证路由跳转
直接查找页面元素容易受异步渲染影响,改用监听路由路径变化来验证:
先修改渲染函数,使用MemoryRouter并暴露history对象:
import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; const renderLoginPage = () => { const history = createMemoryHistory(); render( <Provider store={Store()}> <Router location={history.location} navigator={history}> <LoginPage /> </Router> </Provider> ); return { history }; };
然后在测试用例中检查路径:
test('Valid username, password: ', async () => { const { history } = renderLoginPage(); // ...输入账号密码并点击提交 await waitFor(() => { // 验证是否跳转到Profile页面的路径(比如'/profile',根据实际路由改) expect(history.location.pathname).toBe('/profile'); }); });
3. 放宽元素匹配条件
如果一定要验证页面元素,调整文本匹配规则,避免因文本拆分或选择器问题导致查找失败:
await waitFor(() => { // 用正则匹配文本,忽略大小写 const profileHeading = screen.getByText(/Profile pages/i, { selector: 'p' }); expect(profileHeading).toBeInTheDocument(); }); // 或者用queryByText避免直接抛出错误,再判断是否存在 const profileHeading = await waitFor(() => screen.queryByText('Profile pages', { selector: 'p' })); expect(profileHeading).toBeInTheDocument();
4. 验证Redux状态更新
确保登录成功后Redux状态正确更新,触发组件重渲染:
test('Valid username, password: ', async () => { const store = Store(); render( <Provider store={store}> <BrowserRouter> <LoginPage /> </BrowserRouter> </Provider> ); // ...输入提交 await waitFor(() => { const state = store.getState(); // 检查store中是否存在登录token或用户信息 expect(state.auth.token).toBeTruthy(); }); });
优先推荐方案
先Mock API,再通过验证路由路径来确认跳转,最后按需验证页面元素或Redux状态,这样测试更稳定可靠。
内容的提问来源于stack exchange,提问作者Ram Chander
相关产品推荐
相关产品推荐

