React Fetch测试失败排查:为何无法匹配预期文本?
问题:React Fetch测试未得到预期结果
我模仿视频中的React Fetch测试代码,代码和视频内容高度接近,但测试失败——应用运行时能正常显示“Name: bill”,但测试里找不到这个文本,错误信息如下:
Unable to find an element with the text: Name: bill. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
Ignored nodes: comments, script, style
<body> <div> <div class="App"> <header class="App-header"> <div> <div> <span> Name: </span> </div> </div> </header> </div> </div> </body>12 | } as any) 13 | render(<App />); > 14 | await waitFor(() => expect(screen.getByText("Name: bill")).toBeInTheDocument); | ^ 15 | }); 16 | at waitForWrapper (node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/wait-for.js:166:27) at Object.<anonymous> (src/App.test.tsx:14:16)
应用代码
mydata.json
{"name":"bill","age":"50"}
Api.tsx
import React, {useEffect, useState} from 'react'; export default function FileUploadPage(){ const [name, setName] = useState(""); useEffect(() => { fetch('mydata.json') .then(res => res.json()) .then(res => setName(res.name)) .catch(console.error) }, []) return( <div> <span>Name: {name}</span> </div> ) }
AppContainer.tsx
import React from 'react'; import FileUploadPage from './Api.tsx'; export default function MyContainer() { return( <div> <FileUploadPage /> </div> ); }
App.js
import React from "react"; import './App.css'; import MyContainer from "./components/AppContainer.tsx"; function App() { return ( <div className="App"> <header className="App-header"> <MyContainer /> </header> </div> ); } export default App;
测试代码
import { render, screen, waitFor } from '@testing-library/react'; import App from './App'; import React from 'react'; global.fetch = jest.fn(); const mockFetch = fetch as jest.MockedFunction<typeof fetch>; it.only('fetch call', async () => { mockFetch.mockResolvedValue({ json: () => Promise.resolve("bill") } as any) render(<App />); await waitFor(() => expect(screen.getByText("Name: bill")).toBeInTheDocument); });
请问我哪里操作出错了?
解答
你的问题出在两个地方:
- Mock的fetch返回值不符:实际应用中
res.json()返回的是包含name字段的对象(比如{"name":"bill"}),你通过res.name拿到bill赋值给状态。但测试里你让json()直接返回字符串"bill",此时res.name会是undefined(字符串没有name属性),页面只会显示Name:,自然找不到Name: bill。 - 断言方法调用错误:
toBeInTheDocument是函数,需要加括号调用,否则不会执行断言逻辑。
修正后的测试代码:
it.only('fetch call', async () => { mockFetch.mockResolvedValue({ json: () => Promise.resolve({ name: "bill" }) // 改为包含name字段的对象 } as any) render(<App />); await waitFor(() => expect(screen.getByText("Name: bill")).toBeInTheDocument()); // 补全括号 });
修改后测试即可正常通过。
内容的提问来源于stack exchange,提问作者chocalaca
相关产品推荐
相关产品推荐

