如何使用React Testing Library测试页面重载后是否重定向到Screen1
测试实现方案
核心思路
React Testing Library运行在jsdom环境下,无法执行真实的页面刷新操作。我们可以通过重置应用所有上下文状态+重新挂载根组件的方式模拟页面重载行为,核心要保留重载后不变的属性(当前页面路径),重置会被刷新清空的属性(Redux store数据、组件内部状态)。
前置依赖
确保你已经安装以下测试工具:
@testing-library/reactv13+@testing-library/jest-domredux-mock-store(可选,用于快速构造指定状态的Redux store)react-router-domv5/v6 对应测试适配
具体测试用例实现
用例1:验证无对应Redux值时,重载后正确重定向到Screen1
import { render, screen, fireEvent } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import App from './App'; // 替换为你的根组件路径 const mockStore = configureMockStore([]); describe('页面重载重定向逻辑', () => { it('重载后Redux无对应值时,从Screen2重定向到Screen1', async () => { // 步骤1:模拟初始状态:处于Screen2页面,Redux有对应有效值 const initialStoreWithValue = mockStore({ yourRequiredKey: 'valid_value' // 替换为Screen2依赖的Redux字段 }); render( <MemoryRouter initialEntries={['/screen2']}> {/* 替换为你Screen2的实际路由 */} <Provider store={initialStoreWithValue}> <App /> </Provider> </MemoryRouter> ); // 确认当前处于Screen2 expect(screen.getByText('Screen2的标识文本')).toBeInTheDocument(); // 步骤2:模拟点击重载按钮 fireEvent.click(screen.getByRole('button', { name: '重载' })); // 替换为你重载按钮的识别属性 // 步骤3:模拟页面重载:销毁旧实例,用无对应值的新store、相同路由重新挂载应用 const storeWithoutValue = mockStore({ yourRequiredKey: undefined // 模拟重载后Redux丢失对应值 }); // 卸载之前的组件(React Testing Library v18+可直接调用render返回的unmount方法) const { unmount } = render( <MemoryRouter initialEntries={['/screen2']}> <Provider store={storeWithoutValue}> <App /> </Provider> </MemoryRouter> ); unmount(); // 重新挂载模拟刷新完成 render( <MemoryRouter initialEntries={['/screen2']}> <Provider store={storeWithoutValue}> <App /> </Provider> </MemoryRouter> ); // 断言:已经重定向到Screen1,Screen2内容消失 expect(screen.getByText('Screen1的标识文本')).toBeInTheDocument(); expect(screen.queryByText('Screen2的标识文本')).not.toBeInTheDocument(); }); })
用例2:验证重载后应用不会崩溃
it('重载后reducer返回有效值时应用无崩溃', () => { // 捕获全局错误,判断是否有未捕获的崩溃错误 const originalError = console.error; console.error = jest.fn(); const storeWithValidValue = mockStore({ yourRequiredKey: 'valid_value', // 模拟所有reducer返回有效值,无undefined返回 }); render( <MemoryRouter initialEntries={['/screen2']}> <Provider store={storeWithValidValue}> <App /> </Provider> </MemoryRouter> ); // 断言没有抛出崩溃级别的错误 expect(console.error).not.toHaveBeenCalledWith(expect.stringContaining('undefined')); expect(screen.getByText('Screen2的标识文本')).toBeInTheDocument(); // 恢复console.error原生实现 console.error = originalError; });
注意事项
- 不要在测试中调用真实的
window.location.reload(),该操作会中断jsdom的测试执行 - 如果你的路由配置是严格按path匹配渲染组件,需要把示例中的
Screen1、Screen2路由替换为你项目里的实际路径 - 如果你没有使用
redux-mock-store,也可以直接用你项目里的真实Redux store,重载前清空对应字段的值即可
内容的提问来源于stack exchange,提问作者fahad991
相关产品推荐
相关产品推荐

