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

React 19 use API与NextJS 15异步参数的测试方案咨询

测试Next.js 15中用React 19 use API处理Promise参数的客户端组件

背景

在Next.js 14里,我们测试带动态URL参数的客户端组件/页面时,写法如下:

type PageProps = {
    params: { date: string }
}

const SomePage: FC<PageProps> = ({ params }) => {
    const { date } = params;
    // ...组件逻辑
}

对应的测试代码:

it('renders expected week', () => {
    render(<SomePage params={{ date: '2024-03-20' }} />);
    expect(screen.getByText('THIS WEEK')).toBeInTheDocument();
});

升级到Next.js 15后,params变成了Promise类型,需要用React 19的use API解析:

type PageProps = {
    params: Promise<{ date: string }>
}

const SomePage: FC<PageProps> = ({ params }) => {
    const { date } = use(params);
    // ...组件逻辑
}

遇到的问题

我们尝试直接传入Promise.resolve({ date: '2024-03-20' })作为params,但测试中Promise始终无法resolve,断言失败:

it('renders expected week', async () => {
    render(<Page params={Promise.resolve({ date: '2024-03-20' })} />);
    expect(screen.getByText('THIS WEEK')).toBeInTheDocument();
});

而改用useEffect手动解析Promise的写法,测试能正常运行:

const SomePage: FC<PageProps> = ({ params }) => {
const [date, setDate] = useState("");
useEffect(() => {
  params.then((resolvedParams) => {
    setDate(resolvedParams.date);
  });
});
// ...组件逻辑
}

最佳测试方案

要正确测试用use API处理Promise参数的组件,核心是等待React完成Promise解析和组件重渲染,以下是几种可行方式:

1. 用waitFor等待组件更新

React的use API会在Promise resolve后触发组件重渲染,同步断言会在更新前执行,因此需要用Testing Library的waitFor包裹断言,等待目标元素出现:

it('renders expected week', async () => {
    render(<SomePage params={Promise.resolve({ date: '2024-03-20' })} />);
    await waitFor(() => {
        expect(screen.getByText('THIS WEEK')).toBeInTheDocument();
    });
});

2. 用Next.js官方测试工具的异步render

Next.js提供的next/testing包中的render是异步函数,能自动处理React 19的异步渲染逻辑,无需额外编写waitFor:

import { render } from 'next/testing';

it('renders expected week', async () => {
    await render(<SomePage params={Promise.resolve({ date: '2024-03-20' })} />);
    expect(screen.getByText('THIS WEEK')).toBeInTheDocument();
});

3. 提前让Promise进入resolved状态(可选)

如果想确保Promise在渲染前就已resolve,可以先await目标Promise,再传入组件:

it('renders expected week', async () => {
    const mockParams = Promise.resolve({ date: '2024-03-20' });
    await mockParams; // 让Promise提前进入resolved状态
    render(<SomePage params={mockParams} />);
    await waitFor(() => {
        expect(screen.getByText('THIS WEEK')).toBeInTheDocument();
    });
});

失败原因说明

React 19的use API处理Promise时会触发异步渲染更新,你之前的测试是同步执行断言,此时Promise尚未resolve、组件未完成更新,自然找不到目标元素。使用waitFor或异步render就能等待组件更新完成后再执行断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:04:54