2

I'm trying to test a component in React that uses RTK Query + MSW + Vitest. It works fine on the browser but while testing RTK Query with vitest it throws this error:

{ status: 'FETCH_ERROR', error: 'TypeError: fetch failed' }

I've setup a public repo with the configuration i'm using to replicate the error.

Another error RTK Query throws only while testing is:

TypeError: Failed to parse URL from /api/test?page=1&limit=10

This happens when i setup the fetchBaseQuery - baseUrl as empty or as a relative URL. I have to specify 'http://localhost...' or it wont work. But, it works in the browser.

Repo with the error

Followed some articles on the matter with no success Searched Stackoverflow and found Searched RTK query repo issues and found a similar issue but with jest instead of vitest I've tried clearing query cache between tests - no success.

App.jsx

import { useTestQuery } from "./services/test";

export const App = () => {
  const { data } = useTestQuery({ page: 1, limit: 10 });
  console.log(data);
  return (
    <>
      <h1>{data ? data.data.map((i) => i) : "loading"}</h1>
    </>
  );
};

redux/index.js

import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { testApi } from "../services/test";

const store = configureStore({
  reducer: {
    [testApi.reducerPath]: testApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat([testApi.middleware]),
});
setupListeners(store.dispatch);

export default store;

services/apiSetup.js

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const emptyApi = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl:"http://localhost:3000"
  }),
  tagTypes: ["test"],
  endpoints: () => ({}),
});

services/test.js

import { emptyApi } from "./apiSetup";

export const testApi = emptyApi.injectEndpoints({
  endpoints: (build) => ({
    test: build.query({
      query: ({ page = 1, limit = 10 }) => {
        return { url: `test?page=${page}&limit=${limit}` };
      },
      providesTags: ["test"],
      transformErrorResponse: (result) => console.log(result),
    }),
  }),
  overrideExisting: false,
});

export const { useTestQuery,usePrefetch } =
  testApi;

mocks/server.js

import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const server = setupServer(...handlers);

mocks/handler.js

import { test } from "./handlers/test";

export const handlers = [...test];

mocks/handlers/test.js

import { rest } from "msw";

function randomIntFromInterval(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

export const test = [
  rest.get("http://localhost:3000/test", (req, res, ctx) => {
    console.log(req)
    return res(
      ctx.delay(randomIntFromInterval(100, 1000)),
      ctx.status(200),
      ctx.json({ data: [1, 2, 3, 4, 5], total: 5 })
    );
  }),
];

testSetup.js

import { expect, afterEach, vi } from "vitest";
import { server } from "../mocks/server";
import { cleanup } from "@testing-library/react";
import matchers from "@testing-library/jest-dom";

// extends Vitest's expect method with methods from react-testing-library
expect.extend(matchers);


beforeAll(() => server.listen({ onUnhandledRequest: "bypass", cors: true }));

afterEach(() => {
  server.resetHandlers();
  cleanup();
});

afterAll(() => server.close());

App.test.jsx

import React from "react";
import { describe, expect, test } from "vitest";
import { render, screen } from "@testing-library/react";
import { Provider } from "react-redux";
import store from "../../redux";
import App from "./";

const wrapper = (children) => {
  return <Provider store={store}>{children}</Provider>;
};

function setup(jsx) {
  return {
    ...render(wrapper(jsx)),
  };
}

describe("App test", () => {
  test("Should test", async () => {
    setup(<App />);
    await screen.findByText(/12345/);
    screen.debug(undefined, 50000);
  });
});
Casuso
  • 39
  • 6

2 Answers2

1

Try to install msw 1.1.0, after release https://github.com/mswjs/msw/pull/1545 everything seems to work fine with your setup.

Chiril
  • 59
  • 5
1

If you get FETCH_ERROR in your tests with RTK Query, MSW, vitest, then most likely you'll need to define fetch in a setup function, similar to: https://github.com/reduxjs/redux-toolkit/blob/67a69e876812282ad7fe5590d173a88bd7b80282/packages/toolkit/jest.setup.js

//@ts-ignore
const nodeFetch = require('node-fetch')
//@ts-ignore
global.fetch = nodeFetch
//@ts-ignore
global.Request = nodeFetch.Request
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259