How to snapshot-test a component that does async data loading using react-testing-library?
Asked Answered
D

1

5

So far, in the projects I'm working on, I usually snapshot-test my components that does async data loading this way:

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

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

I find it very handy, because it allows to have a snapshot containing the different states of the component (loading, errors, loaded data).

The thing is that I just found out that this method was not recommended at all, and that the latest updates of the @testing-library/react package don't allow me to test my components this way anymore.

According to the eslint rules of the package, I would have to modify my code like this:

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

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

It works, but the generated snapshot contains only the initial state of the component (in this case, "loading").

How would you do in this situation to efficiently snapshot-test a component loading data asynchronously?

Deane answered 12/11, 2020 at 10:54 Comment(0)
H
12

You are on the right track. The only thing left is to wait for your data to be loaded before you make your assertion.

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

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

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

I used the loading text since you mentioned it on your question. But you can also wait for your data to appear on screen:

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

Great job on noticing the waitFor issue and fixing it!

Haircut answered 14/11, 2020 at 13:14 Comment(3)
Oh, I hadn't thought of that. Clever and efficient!Deane
What is screen here?Sotelo
@Sotelo does this help testing-library.com/docs/queries/about/#screen ?Haircut

© 2022 - 2024 — McMap. All rights reserved.