1

I am trying to set up tests to test a Remix loader and noticed that the request function from graphql-request haphazardly fails when using MSW. If I replace this and use a simple fetch for the requests the tests pass.

Is there any configuration I need to change? I have created a sample repo that demonstrates the bug. The bug gets worse the more tests you have that are using the same mocked request.

Sample repo: https://github.com/charklewis/sb9or3

Here is a summary of the code I am using:

//modules/database.server
import { GraphQLClient } from "graphql-request";
const client = new GraphQLClient("http://some-graphql-api.com/api/graphql", {});

export const fetchQuery = async (query: any, variables: any) => {
  try {
    const response = await client.request(query, variables || {});
    return response;
  } catch (error) {
    return {};
  }
};

//routes/index
import type { LoaderFunction } from "remix";
import { json } from "remix";
import { gql } from "graphql-request";
import { fetchQuery } from "~/modules/database.server";

export const loader: LoaderFunction = async () => {
  const query = gql`
    query MyQuery {
      demoQuery {
        value
      }
    }
  `;
  const response = await fetchQuery(query, {});
  return json({ value: response.demoQuery.value });
};
//routes/__tests__/index
import { graphql } from "msw";
import { setupServer } from "msw/node";
import { loader } from "~/routes/index";

const createServer = (handlers: any[] = []) => {
  const server = setupServer(...handlers);
  beforeAll(() => server.listen({ onUnhandledRequest: "bypass" }));
  afterAll(() => server.close());
  afterEach(() => server.resetHandlers());
  return server;
};


const createDemoQueryHandler = ({ value = true } = {}) => {
  return graphql.query("MyQuery", (req, res, ctx) => {
    return res(ctx.data({ demoQuery: { value } }));
  });
};

createServer([createDemoQueryHandler()]);

test("the loader returns data (round 1)", async () => {
  const response = await loader({
    request: new Request("/", { method: "GET" }),
    params: {},
    context: {},
  });
  const data = await response.json();
  expect(data.value).toBe(true);
});

My vitest configuration is:

/// <reference types="vitest" />
/// <reference types="vite/client" />

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [react(), tsconfigPaths()],
  test: {
    globals: true,
    environment: "jsdom",
    setupFiles: "./app/test-utils.ts",
    testTimeout: 20000
  }
});
Charklewis
  • 4,427
  • 4
  • 31
  • 69

0 Answers0