Как сделать снимок-тест компонента, который выполняет асинхронную загрузку данных с помощью библиотеки react-testing-library?

Пока что в проектах, над которыми я работаю, я обычно тестирую свои компоненты с помощью моментальных снимков, которые выполняют асинхронную загрузку данных следующим образом:

describe('MyComponent component', () =>{
    test('Matches snapshot', async () => {
        fetch.mockResponse(JSON.stringify(catFacts));

        const { asFragment } = render(<MyComponent />);
        await waitFor(() => expect(asFragment()).toMatchSnapshot());
    })
})

Мне это очень удобно, потому что он позволяет получить снимок, содержащий различные состояния компонента (загрузка, ошибки, загруженные данные).

Дело в том, что я только что узнал, что этот метод вообще не рекомендуется, и что последние обновления пакета @testing-library/response не позволяют мне больше тестировать мои компоненты таким образом.

Согласно правилам пакета eslint, мне пришлось бы изменить свой код следующим образом:

describe('MyComponent component', () =>{
    test('Matches snapshot', () => {
        fetch.mockResponse(JSON.stringify(catFacts));

        const { asFragment } = render(<MyComponent />);
        expect(asFragment()).toMatchSnapshot();
    })
})

Это работает, но сгенерированный снимок содержит только начальное состояние компонента (в данном случае "загрузка").

Как бы вы поступили в этой ситуации, чтобы эффективно протестировать моментальный снимок компонента, загружающего данные асинхронно?

1 ответ

Решение

Ты на правильном пути. Осталось только дождаться загрузки ваших данных, прежде чем делать свое утверждение.

describe('MyComponent component', async () =>{
    test('Matches snapshot', () => {
        fetch.mockResponse(JSON.stringify(catFacts));
        
        const { asFragment } = render(<MyComponent />);

        await waitForElementToBeRemoved(screen.getByText('loading'));

        expect(asFragment()).toMatchSnapshot();
    })
})

Я использовал loadingтекст, так как вы упомянули об этом в своем вопросе. Но вы также можете подождать, пока ваши данные появятся на экране:

await screen.findByText('something that comes from the mocked data');

Отличная работа по замечанию waitFor проблема и исправление!

Другие вопросы по тегам