Failed to mock requests from suspended component
s1n7ax opened this issue · 1 comments
s1n7ax commented
I have a component that waits until some data from a resource. I'm using React suspense to show the loading screen as until it gets the response. When testing, even though onGet
is registered, in axiosMock
, it never gets the request from <Cmp />
component. Test fails due to network error.
Example code:
import { render, waitFor } from '@testing-library/react';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import React, { Suspense } from 'react';
const axiosMock = new MockAdapter(axios, { onNoMatch: 'throwException' });
const wrapPromise = (promise) => {
let status = 'pending';
let result: any;
promise.then(
(r) => {
status = 'success';
result = r;
},
(e) => {
status = 'error';
result = e;
}
);
return {
read() {
return {
status,
result,
};
},
};
};
const fetchData = () => {
return wrapPromise(axios.get('/test').then((r) => r.data));
};
const resource = fetchData();
export const Cmp = () => {
const str = resource.read();
return <h1>{str}</h1>;
};
describe('Main Tests', () => {
beforeAll(() => {
axiosMock.reset();
});
/*
THIS WORKS
*/
it('Sample Request Test', async () => {
axiosMock.onGet('/test').reply(200, 'hello');
expect(await axios.get('/test').then((r) => r.data)).toBe('hello');
});
/*
THIS DOES NOT WORK
*/
it('Component Request Test', async () => {
axiosMock.onGet('/test').reply(200, 'hello');
const { getByText } = render(
<Suspense fallback={<p>Loading...</p>}>
<Cmp />
</Suspense>
);
await waitFor(() => {
return getByText('hello');
});
});
});
marcbachmann commented
You already execute the axios request in your fetchData()
request, which is too early.
const fetchData = () => {
return wrapPromise(axios.get('/test').then((r) => r.data));
};
const resource = fetchData();
Not sure how you should structure the code with suspense, but you should delay the fetching until the component is initialized (maybe in a mounted hook or something similar)