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

React18升级后Jest测试中userEvent.type报错:Expected key descriptor but found ""

React18升级后测试用例输入操作失败问题

测试用例在React16环境运行正常,升级React18后执行输入过滤表格的测试时失败。示例代码如下:

const Wrapper = () => (
  <Provider store={store}>
    <TestComponent testId={'table-view'} />
  </Provider>
);
it('Recently Added Search : test', async () => {
    await render(<Wrapper />);
    await waitFor(
      async () => {
        store.dispatch(setTabIndex(1));
        const searchComp = screen.getByTestId('recent-search-input');
        userEvent.type(searchComp, 'ABC');

        const table = await screen.getByRole('recentTable');
        expect(table).toHaveAttribute('aria-colcount', '4');
        expect(table).toHaveAttribute('aria-rowcount', '0');
      },
      { timeout: 5000 }
    );
  });

错误信息:

Expected key descriptor but found "" in ""
at assertDescriptor
(node_modules/@testing-library/user-event/dist/cjs/utils/keyDef/readNextDescriptor.js:77:15) at readPrintableChar
(node_modules/@testing-library/user-event/dist/cjs/utils/keyDef/readNextDescriptor.js:33:5)
at Object.readNextDescriptor
(node_modules/@testing-library/user-event/dist/cjs/utils/keyDef/readNextDescriptor.js:28:26) at Object.parseKeyDef
(node_modules/@testing-library/user-event/dist/cjs/keyboard/parseKeyDef.js:26:125)
at Object.keyboard
(node_modules/@testing-library/user-event/dist/cjs/keyboard/index.js:17:33) at Object.type
(node_modules/@testing-library/user-event/dist/cjs/utility/type.js:26:16)
at Object.asyncWrapper
(node_modules/@testing-library/react/dist/pure.js:73:22)

已尝试添加await调用userEvent.type,问题仍未解决。

解决方案

以下是针对性的修复步骤,按优先级尝试:

1. 升级@testing-library/user-event到兼容版本

React18要求使用@testing-library/user-event v14及以上版本,旧版本与React18的并发渲染机制不兼容,会触发输入解析错误。执行升级命令:

npm install @testing-library/user-event@latest
# 或
yarn add @testing-library/user-event@latest

2. 使用userEvent.setup()创建实例(v14+强制要求)

新版本user-event不再支持直接调用静态方法,需先初始化实例再操作:

it('Recently Added Search : test', async () => {
    const user = await userEvent.setup();
    await render(<Wrapper />);
    
    await waitFor(async () => {
        store.dispatch(setTabIndex(1));
        // 用findByTestId确保元素已挂载且可交互
        const searchComp = await screen.findByTestId('recent-search-input');
        await user.type(searchComp, 'ABC');
        
        // 修正表格查询:getByRole参数为标准ARIA角色,自定义ID用getByTestId
        const table = screen.getByTestId('recentTable');
        expect(table).toHaveAttribute('aria-colcount', '4');
        expect(table).toHaveAttribute('aria-rowcount', '0');
    }, { timeout: 5000 });
});

3. 调整元素查询与状态同步逻辑

  • 替换同步查询screen.getByTestId为异步的await screen.findByTestId:React18并发渲染下,元素可能延迟挂载,findBy会自动等待元素出现。
  • 新增状态同步等待:dispatch动作后,等待Redux状态更新到组件,避免操作未就绪的元素:
it('Recently Added Search : test', async () => {
    const user = await userEvent.setup();
    await render(<Wrapper />);
    
    store.dispatch(setTabIndex(1));
    // 等待Tab索引状态更新完成
    await waitFor(() => expect(store.getState().tabIndex).toBe(1));
    
    const searchComp = await screen.findByTestId('recent-search-input');
    await user.type(searchComp, 'ABC');
    
    const table = await screen.findByTestId('recentTable');
    expect(table).toHaveAttribute('aria-colcount', '4');
    expect(table).toHaveAttribute('aria-rowcount', '0');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:05:29