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

如何在执行matchSnapshot测试前等待API返回结果

React异步请求组件快照测试失败解决方案

问题根源

你当前的测试存在3个核心错误:

  • 无效等待:await mockGetMovies 等待的是mock函数对象本身,不是函数执行后返回的Promise实例,完全没有等接口返回、状态更新的逻辑执行完成
  • 不必要的手动act包裹:你使用的@testing-library/react内部已经自动对所有更新逻辑做了act封装,手动包裹反而容易导致状态更新没有被正确捕获
  • 未等待异步重渲染完成就执行快照:组件拿到接口返回后需要执行setMovies触发重渲染,你在重渲染执行前就对container做了快照,自然只能拿到加载中状态

修正后的测试代码

import React from 'react';
import { render, screen } from '@testing-library/react';
import { getMovies } from '../app/requests/getMovies';
import Home from '.';

jest.mock('../app/requests/getMovies');
const mockGetMovies = getMovies as jest.Mock;

describe('/', () => {
  beforeEach(() => {
    mockGetMovies.mockResolvedValue([
      {
        Title: 'Titanic',
      },
    ]);
  });

  it('should render the homepage', async () => {
    const { container } = render(<Home />);
    // 异步等待目标元素渲染完成,内部自动处理act逻辑
    await screen.findByText('Movies (1)');
    // 此时生成的快照就是加载完成后的预期状态
    expect(container).toMatchInlineSnapshot(`
      <div>
        <main>
          <h1>
            Movies (1)
          </h1>
        </main>
      </div>
    `);
  });
});

方案说明

  • findBy* 是React Testing Library提供的异步查询API,内部自动结合了等待逻辑和act封装,会持续查询直到匹配到对应元素或者超时,刚好适配组件异步请求后重渲染的场景
  • 如果你不想依赖文本查询,也可以用waitFor包裹断言逻辑,效果完全一致:
    await waitFor(() => {
      expect(screen.getByRole('heading', { name: /Movies \(1\)/ })).toBeInTheDocument();
    })
    

内容的提问来源于stack exchange,提问作者coding1223322

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:15:04