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 */
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.