如何在Jest中模拟包含数组的对象响应数据?
在React Native中用Jest模拟Axios响应测试componentWillMount
要在你的单元测试中模拟指定格式的响应数据,核心是mock Axios的get请求,让它返回你预设的测试数据。下面是具体的实现步骤和修改后的测试代码:
第一步:准备模拟的响应数据
先定义好你需要的测试数据,比如你给出的示例,还可以额外加一条符合Active状态的数据,这样能验证你的过滤逻辑是否生效:
const mockResponse = { data: [ { "_id": "5acb16701e09ae8abc29e7fb", "courseName": "Agile Fundamentals420", "category": "Agile", "coursetype": "Instructor-Led", "duration": 22, "addnote": "contractor", "status": "Completed", "registrations": 10 }, { "_id": "test-active-course", "courseName": "Active Test Course", "category": "DevOps", "coursetype": "Instructor-Led", "duration": 15, "addnote": "active test", "status": "Active", "registrations": 8, "location": "New York" } ] };
第二步:Mock Axios的get方法
在测试用例中,用Jest的spyOn来mock Axios的get方法,让它返回我们预设的响应数据的Promise:
const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValue(mockResponse);
第三步:修改测试用例,处理异步逻辑
因为componentWillMount里包含异步的Axios请求,所以测试用例需要加上async/await来等待异步操作完成,否则测试会提前结束,无法验证状态更新。
修改后的完整测试用例
import axios from 'axios'; import Instructor_cata from './path-to-your-component'; // 替换成你的组件实际路径 import { shallow } from 'enzyme'; // 假设你用Enzyme做组件浅渲染 it('should fetch and process course data in componentWillMount', async () => { // 1. 定义模拟响应数据 const mockResponse = { data: [ { "_id": "5acb16701e09ae8abc29e7fb", "courseName": "Agile Fundamentals420", "category": "Agile", "coursetype": "Instructor-Led", "duration": 22, "addnote": "contractor", "status": "Completed", "registrations": 10 }, { "_id": "test-active-course", "courseName": "Active Test Course", "category": "DevOps", "coursetype": "Instructor-Led", "duration": 15, "addnote": "active test", "status": "Active", "registrations": 8, "location": "New York" } ] }; // 2. Mock Axios get请求 const axiosGetSpy = jest.spyOn(axios, 'get').mockResolvedValue(mockResponse); // 3. 渲染组件并获取实例 const wrapper = shallow(<Instructor_cata navigation={navigation}/>); const instance = wrapper.instance(); // 4. 调用componentWillMount并等待异步操作完成 await instance.componentWillMount(); // 5. 验证请求是否正确发起 expect(axiosGetSpy).toHaveBeenCalledWith(SERVER_URL + '/courses'); // 6. 验证状态是否正确更新 expect(instance.state.loading).toBe(true); // 初始设置的loading状态 // 只有第二条数据符合Active+Instructor-Led,所以trainingcatalogues长度应为1 expect(instance.state.trainingcatalogues.length).toBe(1); expect(instance.state.Location1).toEqual(['New York']); expect(instance.state.Category1).toEqual(['DevOps']); expect(instance.state.Location2).toEqual(['All']); expect(instance.state.Category2).toEqual(['All']); // 7. 清理mock,避免影响其他测试用例 axiosGetSpy.mockRestore(); });
重要提醒:修复组件中的状态更新问题
看你的componentWillMount代码,直接修改this.state(比如this.state.trainingcatalogues = [])是不符合React规范的,React要求必须通过this.setState来更新状态,否则组件不会重新渲染,而且状态更新可能不可预测。
修改你的组件代码:
componentWillMount() { this.setState({ loading: true }); axios.get(SERVER_URL + '/courses') .then(response => { // 先初始化临时变量存储处理后的数据 const trainingcatalogues = []; const traininglist = []; const Location1 = []; const Category1 = []; const Location2 = ['All']; const Category2 = ['All']; for (var key in response.data) { const course = response.data[key]; if (course.coursetype === 'Instructor-Led' && course.status === 'Active' ) { Location1.push(course.location); Category1.push(course.category); trainingcatalogues.push(course); traininglist.push(course); } } // 用setState更新状态 this.setState({ trainingcatalogues, traininglist, Location1, Category1, Location2, Category2, loading: false // 建议请求完成后把loading设为false }); }) .catch(error => { // 别忘了处理请求失败的情况 console.error('Failed to fetch courses:', error); this.setState({ loading: false }); }); }
这样你的状态更新才是正确的,测试也能准确验证状态变化。
内容的提问来源于stack exchange,提问作者komalV
相关产品推荐
相关产品推荐

