Search code examples
reactjsreact-testing-libraryreact-admints-jest

react-admin, the unit-test of a List-page can't see the mock data


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

Solution

  • 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.