0

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. Everything work as expected.

However when testing, even though onGet is registered, in axiosMock, it never gets the request from <Cmp /> component. Test fails due to connection error.

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');
    });
  });
});

s1n7ax
  • 2,750
  • 6
  • 24
  • 53
  • You say the component works, by manual testing I assume, but shouldn't the call to resource.read in Cmp be in a useEffect hook since it is async? Could be the source of unexpected errors. – James Aug 02 '21 at 20:44
  • As the documentation suggests, read call lives outside the useEffect. Main goal is to stop the execution by throwing a promises. I assume catch the throw. If it is a promise, it waits until it to be completed then proceed. – s1n7ax Aug 02 '21 at 21:34

0 Answers0