使用react-testing-library和Jest测试React CRA项目API调用遇函数错误
问题:测试React组件中useEffect触发的API调用时出现"getCoords is not a function"错误
在Create React App(CRA)项目中,尝试使用react-testing-library和Jest测试App.js里由useEffect钩子触发的getCoords API调用函数,已经配置了axios模拟数据,但运行npm test时控制台报错:TypeError: (0 , _App.getCoords) is not a function。需要验证组件加载时该API调用是否正常执行,作为测试新手,询问是否需要模拟getCoords函数。
报错详情
console.error
TypeError: (0 , _App.getCoords) is not a function
30 | 31 | // when > 32 | const result = await getCoords(); | ^ 33 | 34 | // then 35 | expect(axios.get).toHaveBeenCalledWith(baseURL);
测试代码(App.test.js)
import { render, waitForElement } from '@testing-library/react'; import axios from 'axios'; import { baseURL, getCoords } from './App' import App from './App'; // console.log(getCoords) jest.mock("axios"); const coords = [ { _id: "63c56b4dd6402c9bd41bef78", lng: -74.03903, lat: 41.02881, false: false }, { _id: "63c56b4dd6402t7bd41bef78", lng: -74.05648, lat: 41.95185, false: false } ]; describe('getCoords', () => { it("should return coordinates data", async () => { axios.get.mockResolvedValue({ data: coords}); // render // render(<App />); // when const result = await getCoords(); // then expect(axios.get).toHaveBeenCalledWith(baseURL); expect(result).toEqual(coords); }); });
App.js代码片段
const App = () => { .... // Getting all coords const getCoords = () => { axios.get(baseURL) .then((res) => { console.log(res.data) setCoords(res.data) }) .catch((error) => console.error(error)) } ... return( <BrowserRouter> <header className="sticky text-center w-screen"> <Routes> <Route index element={<Header/>}></Route> <Route path="/list" element={<NavHeader/>}> <Route path=":id" ></Route> <Route path=":id/edit" ></Route> </Route> <Route path="/map" element={<NavHeader/>}></Route> </Routes> </header> <main className="h-[700px]"> <Routes> <Route index element={<Home handleGeolocate={handleGeolocate} submitStatus={submitStatus} recordSuccess={recordSuccess}/>}></Route> <Route path="/list"> <Route index element={<List coords={coords} handleDelete={handleDelete}/>}></Route> <Route path=":id" element={<EachCoordDetail coords={coords} handleDelete={handleDelete}/>}></Route> <Route path=":id/edit" element={<EachCoordEdit coords={coords} handleEdit={handleEdit}/>}></Route> </Route> <Route path="/map" element={<Map coords={coords} currentLocation={currentLocation}/>}></Route> <Route path="*" element={<NotFound />}></Route> </Routes> </main> </BrowserRouter> )
问题原因与解决方法
报错根本原因
getCoords是定义在App组件内部的函数,并非导出的模块成员,所以无法直接从./App中import调用,这就是报错的核心原因。是否需要模拟getCoords?
不需要。你的测试目标是验证组件加载时的API调用行为,应该聚焦于组件整体逻辑而非单独调用内部函数。正确的做法是渲染组件,断言axios的调用情况,以及组件对数据的处理结果。修正后的测试代码
import { render, waitFor } from '@testing-library/react'; import axios from 'axios'; import { baseURL } from './App' import App from './App'; jest.mock("axios"); const coords = [ { _id: "63c56b4dd6402c9bd41bef78", lng: -74.03903, lat: 41.02881, false: false }, { _id: "63c56b4dd6402t7bd41bef78", lng: -74.05648, lat: 41.95185, false: false } ]; describe('App component', () => { it("should fetch coordinates on mount", async () => { // 模拟axios返回数据 axios.get.mockResolvedValue({ data: coords}); // 渲染组件 render(<App />); // 等待API调用完成,断言axios.get被正确触发 await waitFor(() => { expect(axios.get).toHaveBeenCalledWith(baseURL); }); }); });
- 额外优化建议
- 若要验证组件是否正确渲染了获取到的坐标数据,可以添加页面元素查询逻辑,比如查找列表项是否存在,确保数据被正确展示。
- 如果确实需要单独测试
getCoords函数,建议将其从组件内部提取为独立模块导出,这样才能在测试文件中直接import并调用。
内容的提问来源于stack exchange,提问作者Andrew Saganda
相关产品推荐
相关产品推荐

