英文:
react-admin, the unit-test of a List-page can't see the mock data
问题
我正在尝试对典型的基于列表的react-admin组件进行单元测试。所以我添加了一个带有仅getList()方法(被调用)的模拟dataProvider到AdminContext中。
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();
});
})
然而,似乎没有起作用。输出的HTML DOM中列表中没有行,因此测试失败。
还有这个act
警告,但将渲染调用包装在act()
中并没有改变任何事情,甚至警告仍然存在。
警告:在测试中,没有在act(...)中包装的ListBase内部的更新。
在测试时,导致React状态更新的代码应该包装在act(...)中:
act(() => {
/* 触发更新状态的事件 */
});
/* 对输出进行断言 */
英文:
I’m trying to unit-test a typical List-based react-admin component. So i have a mock dataProvider added to the AdminContext with just the getList() method (which is called).
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();
});
})
Yet, it doesn’t seem to work. The outputted html dom has 0 rows in the list and therefore the test fails.
There is also this act warning, but wrapping the render call in act() doesn’t change anything, even the warning remains.
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
得分: 0
感谢 @slax57
解决方法是将 await screen.getByText()
替换为 await screen.findByText()
基本上,当使用 screen.debug();
记录 HTML 输出时,可以看到屏幕没有填充 API 响应内容(列表没有行),因此等待未激活。一个方法返回一个 promise,而另一个方法则不返回。
英文:
Thanks to @slax57
The solution was to replace await screen.getByText()
by await screen.findByText()
Basically, when logging the html output with screen.debug();
, it can be seen that the screen was not filled with the API response content (list with no rows) so the await was not active. One method returns a promise when the other does not.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论