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

React-admin列表页单元测试无法读取Mock数据问题求助

React Admin List组件单元测试问题排查与解决

问题场景

对基于List的React Admin组件做单元测试,已在AdminContext中配置仅包含getList()方法的mock dataProvider(该方法已被调用),但测试失败且出现act警告。

组件代码

const BookList = (props:any) => {
  return (
      <List {...props}>
        <Datagrid>
          <TextField source='title'/>
        </Datagrid>
      </List>
  )
}

测试代码

describe('list test', () => {
  it('list test', async () => {
    let dataProvider:DataProvider = testDataProvider({
        getList: function <RecordType extends RaRecord<Identifier> = any>(resource: string, params: GetListParams): Promise<GetListResult<RecordType>> {
            let record:RecordType = {
                id:"1",
                title:'myTitle'
            }as unknown as RecordType;
            return Promise.resolve({data:[record],total:1});
        }      
    });

    render(
        <AdminContext dataProvider={dataProvider}>
                <BookList resource='books'/>
        </AdminContext>
    );
    expect(await screen.getByText('myTitle')).toBeInTheDocument();
  });
})

问题表现

  1. 测试失败:DOM中列表行数为0,无法找到myTitle文本
  2. 控制台出现act警告:

Warning: An update to ListBase inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
/* fire events that update state /
});
/
assert on the output */


解决方法

1. 用waitFor替代直接await断言

React Admin的List组件内部会异步请求数据并更新状态,await screen.getByText()无法正确等待所有渲染完成。改用waitFor包裹断言,它会自动处理act的状态更新包裹:

// 替换原断言代码
await waitFor(() => {
  expect(screen.getByText('myTitle')).toBeInTheDocument();
});

2. 补充AdminContext必要配置

List组件依赖i18nProvider上下文,即使使用默认实现也需要显式传入,否则可能导致渲染异常:

import { defaultI18nProvider } from 'react-admin';

// 修改render部分
render(
    <AdminContext 
        dataProvider={dataProvider} 
        i18nProvider={defaultI18nProvider}
    >
        <BookList resource='books'/>
    </AdminContext>
);

3. 确保mock dataProvider返回格式正确

给mock的getList添加日志,确认是否被正确调用,同时保证返回数据结构完全符合React Admin的要求:

getList: function <RecordType extends RaRecord<Identifier> = any>(resource: string, params: GetListParams): Promise<GetListResult<RecordType>> {
    console.log('getList triggered for resource:', resource); // 验证调用情况
    const record: RecordType = {
        id: "1",
        title: 'myTitle'
    } as unknown as RecordType;
    return Promise.resolve({ data: [record], total: 1 });
}

4. 强制List显示所有数据

避免分页逻辑导致数据不显示,给List组件添加perPage参数:

const BookList = (props:any) => {
  return (
      <List {...props} perPage={100}>
        <Datagrid>
          <TextField source='title'/>
        </Datagrid>
      </List>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 02:35:24