Unexpected error object with mock-service-worker and react-query with graphql

70 views Asked by At

I'm writing a test where I expect an error message to show.

This is the component I'm testing:

export const CourseOverview = () => {
  const { data, isError, error, isSuccess } = useGetCourses();

  if (isError) {
    return <div>{error.message}</div>;
  }

  if (isSuccess) {
    return (
      <CourseAccordion items={data.courses} />
    );
  }

  return <div>Loading...</div>;
};

useGetCourses is a custom hook that wraps @tanstack/react-query:

const query = gql(`
  query getCourses($language: LanguageType!) {
    courses(language: $language) {
      academicYearEnd
      academicYearStart
      coursePeriods
      title
    }
  }
`);

export const useGetCourses = () => {
  // queryClient is an instance of graphql-request GraphQLClient
  // with api and headers for auth set
  const { queryClient } = useQueryClient();

  return useQuery({
    queryKey: ['coursesOverview'],
    queryFn: () => queryClient.request(query),
  });
};

In my test I am using MSW to generate an error:

import { graphql, HttpResponse } from 'msw';

describe('CourseOverview', () => {
  it('should render error state', async () => {
    // mockServer is defined and exported in jest-setup as described in the official docs: https://mswjs.io/docs/integrations/node
    mockServer.use(
      graphql.query('getCourses', () => {
        return HttpResponse.json({ errors: [{ message: 'oopsie' }] });
      })
    );

    // renderWithProviders wraps the testing-library render function with QueryClientProvider (see below)
    renderWithProviders(<CourseOverview />);
    expect(await screen.findByText('oopsie')).toBeInTheDocument();
  });
});
export const renderWithProviders = (
  element: JSX.Element
): RenderResult => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  });

  return render(
    <QueryClientProvider client={queryClient}>
      {element}
    </QueryClientProvider>
  );
};

If you look at the component, we are outputting the error.message. So I expect to see: "oopsie".

However, there appears to be a whole response object in it (console.log result in component):

"oopsie: {\"response\":{\"errors\":[{\"message\":\"oopsie\"}],\"status\":200,\"headers\":{}},\"request\":{\"query\":\"query getCourses($language: LanguageType!) {\\n  courses(language: $language) {\\n    academicYearEnd\\n    academicYearStart\\n    coursePeriods\\n    title\\n  }\\n}\",\"variables\":{\"language\":\"NL\"}}}"

The default graphql error is the errors object. We are getting that, but wrapped in response.

I suspect that is because of the HttpResponse.json function in the msw handler, but according to the docs this is how it should be done: https://mswjs.io/docs/api/graphql#graphqllinkurl (line 19).

How can I make MSW return the expected object?
Or is it react-query that doesn't parse the error correctly?

0

There are 0 answers