ra使用ra-data-graphql-simple做Jest测试报错如何解决?
问题原因梳理
- 第一个版本报错
Unknown dataProvider function: getList:你存入state的是provider构造函数,而非实际可用的dataProvider实例,所有实例方法(如getList)都挂载在构造函数执行后的返回值上,因此调用时找不到对应方法。 - 第二个版本报错
Unknown resource undefined:你在组件内部用useEffect异步初始化provider,react状态更新的异步特性会导致子组件挂载时,resource参数未正确传递到上下文,或是构造函数调用时缺少必要配置,无法识别你传入的Client资源。
最优解决方案
不要在测试Wrapper组件内部异步初始化dataProvider,jest测试是同步执行的,要提前在测试setup阶段完成初始化,保证渲染组件时provider已经准备就绪。
第一步:封装通用测试工具
import { render } from '@testing-library/react'; import buildGraphQLProvider from 'ra-data-graphql-simple'; import { AdminContext } from 'react-admin'; import { ThemeProvider } from '@mui/material/styles'; // 根据你实际用的主题库调整 import theme from './your-theme-path'; // 替换为你的主题文件路径 // 缓存初始化完成的provider,避免每次测试重复初始化 let cachedDataProvider: any = null; export const initTestDataProvider = async () => { if (cachedDataProvider) return cachedDataProvider; const providerConstructor = await buildGraphQLProvider({ clientOptions: { uri: 'http://localhost:4000' }, // 如果你的schema命名不符合ra-data-graphql-simple默认约定,在这里加类型映射配置 }); // 对应版本需要调用构造函数才返回实例就保留下面的判断,否则直接赋值providerConstructor即可 cachedDataProvider = typeof providerConstructor === 'function' ? providerConstructor() : providerConstructor; return cachedDataProvider; }; // 自定义渲染函数,自动注入所有需要的Provider export const renderWithRaProviders = async (ui: React.ReactElement, options = {}) => { const dataProvider = await initTestDataProvider(); return render( <AdminContext dataProvider={dataProvider} enableReducers> <ThemeProvider theme={theme}> {ui} </ThemeProvider> </AdminContext>, options ); };
第二步:测试中直接使用封装好的方法
test('ClientList 渲染正常', async () => { const defaultEditProps = { basePath: '/Client', resource: 'Client', hasList: true, location: { hash: '', key: 'igsiaesg', pathname: '/Client', search: '', state: null, }, match: { isExact: true, params: {}, path: '/Client', url: '/Client', }, }; // await 保证provider初始化完成后再渲染组件 await renderWithRaProviders(<ClientList {...defaultEditProps} />); // 后续添加你的断言逻辑即可 });
可选排查点
如果调整后仍然报资源未定义错误,检查两项配置:
- 确认mock服务器的schema中确实定义了
Client类型,且存在对应列表查询的接口(ra-data-graphql-simple默认约定列表查询为all[资源名复数]格式,如allClients,不符的话需要在初始化buildGraphQLProvider时自定义查询映射) - 如果你实际使用的是hasura版本的graphql provider,初始化时需要额外传入资源映射配置,否则无法识别自定义资源。
内容的提问来源于stack exchange,提问作者Jakobl
相关产品推荐
相关产品推荐

