使用Jest和Enzyme测试含API调用的React组件状态
如何用Jest和Enzyme测试React组件的状态变化
我来帮你一步步实现这个组件的状态测试~ 首先咱们得先把你提供的组件代码补全(你贴的render部分截断了),假设完整的组件代码是这样的:
import React, { Component } from 'react'; class App extends Component { constructor(props) { super(props); this.state = { isLoading: false }; this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState({ isLoading: true }); return fetch('https://api.github.com/users/londonappdev') .then(res => res.json()) .then(data => { console.log(data); this.setState({ isLoading: false }); }); } render() { const { isLoading } = this.state; return ( <div> <button onClick={this.handleClick} disabled={isLoading}> {isLoading ? '加载中...' : '获取数据'} </button> </div> ); } } export default App;
接下来咱们分步骤完成测试:
第一步:安装必要依赖
根据你的React版本选择对应的Enzyme适配器(比如React 16用enzyme-adapter-react-16,React 17用@wojtekmaj/enzyme-adapter-react-17),同时安装fetch模拟工具:
npm install --save-dev enzyme enzyme-adapter-react-16 jest-fetch-mock # 或用yarn yarn add --dev enzyme enzyme-adapter-react-16 jest-fetch-mock
第二步:配置测试环境
在项目根目录的src文件夹下创建setupTests.js(Create React App会自动加载这个文件),配置Enzyme和全局fetch mock:
import Enzyme from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import fetchMock from 'jest-fetch-mock'; Enzyme.configure({ adapter: new Adapter() }); // 启用fetch的mock功能 fetchMock.enableMocks();
第三步:编写测试用例
创建App.test.js文件,编写以下测试逻辑,覆盖所有状态变化场景:
import React from 'react'; import { shallow } from 'enzyme'; import App from './App'; describe('App Component', () => { // 每次测试前重置fetch mock,避免测试间的干扰 beforeEach(() => { fetch.resetMocks(); }); // 测试初始状态 it('初始状态下isLoading为false,按钮显示正常文本', () => { const wrapper = shallow(<App />); expect(wrapper.state('isLoading')).toBe(false); expect(wrapper.find('button').text()).toBe('获取数据'); }); // 测试点击按钮后的即时状态变化 it('点击按钮后立即将isLoading设为true,按钮显示加载文本', () => { const wrapper = shallow(<App />); wrapper.find('button').simulate('click'); expect(wrapper.state('isLoading')).toBe(true); expect(wrapper.find('button').text()).toBe('加载中...'); // 确认fetch被调用了正确的API地址 expect(fetch).toHaveBeenCalledWith('https://api.github.com/users/londonappdev'); }); // 测试API请求完成后的状态变化 it('API请求完成后将isLoading设为false,按钮恢复正常文本', async () => { // 模拟API返回的数据 const mockUserData = { login: 'londonappdev', id: 123456 }; fetch.mockResponseOnce(JSON.stringify(mockUserData)); const wrapper = shallow(<App />); wrapper.find('button').simulate('click'); // 等待异步的fetch请求完成 await Promise.resolve(); expect(wrapper.state('isLoading')).toBe(false); expect(wrapper.find('button').text()).toBe('获取数据'); }); });
关键细节说明
- shallow渲染:用
shallow而非mount,因为我们只需要测试组件自身的状态变化,不需要渲染子组件(这里也没有子组件),能让测试更高效。 - fetch mock:用
jest-fetch-mock模拟网络请求,避免真实调用API,保证测试的稳定性和速度。 - 异步测试处理:因为
handleClick包含异步操作,所以用async/await等待Promise完成,确保状态更新后再执行断言,避免测试失败。
内容的提问来源于stack exchange,提问作者LondonAppDev
相关产品推荐
相关产品推荐

