You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:34:58