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

如何使用Jest测试返回Promise的React服务器组件?

解决React Server Component(异步返回Promise)的Jest测试问题

核心问题分析

你写的Home是异步React Server Component(返回Promise<JSX.Element>),但Jest的标准render方法仅支持同步JSX元素,直接用<Home/>会因为它是Promise而非可渲染的同步组件报错:'Home' can not be used as a JSX element。

可行解决方案(无需修改组件逻辑)

方案1:手动解析组件Promise后渲染

既然组件本身是返回Promise的函数,你可以直接调用它(传入对应props),等待Promise resolve拿到真实JSX元素,再传给render:

// home.test.ts
import { render, screen } from '@testing-library/react';
import Home from './Home';

describe('Home', () => {
  it('renders a heading', async () => {
    // 手动调用异步组件并传入所需props
    const jsx = await Home({ /* 这里传入组件需要的props */ });
    // 渲染解析后的同步JSX
    render(jsx);
    
    // 正常编写断言逻辑
    expect(screen.getByRole('heading')).toBeInTheDocument();
  });
});

方案2:封装异步渲染工具函数(提升复用性)

如果有多个异步Server Component需要测试,可以封装一个工具函数统一处理:

// test-utils.ts
import { render, RenderResult } from '@testing-library/react';

export async function renderAsync<TProps>(
  component: (props: TProps) => Promise<JSX.Element>,
  props: TProps
): Promise<RenderResult> {
  const jsx = await component(props);
  return render(jsx);
}

测试中直接使用这个工具函数:

// home.test.ts
import { renderAsync } from './test-utils';
import Home from './Home';

describe('Home', () => {
  it('renders a heading', async () => {
    const { getByRole } = await renderAsync(Home, { /* 传入组件props */ });
    expect(getByRole('heading')).toBeInTheDocument();
  });
});

方案3:Mock组件内部的异步依赖

如果组件内部调用了异步API,测试前可以mock这些依赖,让组件的Promise快速resolve,避免真实网络请求影响测试:

// home.test.ts
import { render, screen } from '@testing-library/react';
import Home from './Home';
// 假设组件内部调用了fetchData这个异步函数
import { fetchData } from './api';

jest.mock('./api');

describe('Home', () => {
  it('renders a heading', async () => {
    // Mock异步函数返回预设数据
    (fetchData as jest.Mock).mockResolvedValue({ /* 模拟接口返回的测试数据 */ });
    
    const jsx = await Home({ /* 传入组件props */ });
    render(jsx);
    
    expect(screen.getByRole('heading')).toBeInTheDocument();
  });
});

注意事项

  • 测试函数必须标记为async,所有异步操作都要用await处理,防止Jest提前结束测试。
  • 以上方法都是提前解析Server Component的Promise,拿到最终要渲染的同步JSX,完全不需要修改原组件的异步逻辑。

内容的提问来源于stack exchange,提问作者Paul van Brenk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:37:48