Jiayu Zhang
Jiayu Zhang

Reputation: 31

Having issues with making tests work with RTK Query and MSW

I am trying to integrate MSW into testing for my Vite app with RTK Query and am having issues with the baseUrl

TLDR: I want to make my RTK query base url /api instead of http://localhost:5173/api/auth but it is not working with MSW.

Prior to adding MSW, my authSlice.ts looked like this:

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

import { User } from './userSlice'

export const authSlice = createApi({
  reducerPath: "auth",
  baseQuery: fetchBaseQuery({ baseUrl: "/api" }),
  tagTypes: ["Auth"],
  endpoints: (builder) => ({
    getAuth: builder.query<User, void>({
      query: () => "/auth",
      providesTags: ["Auth"]
    }),
  }),
});

export const {
  useGetAuthQuery,
} = authSlice;

export type useGetAuthQueryResult = ReturnType<typeof useGetAuthQuery>

The main thing to note is that everything works as expected with the baseUrl set to /api

However, when I included MSW, it didn't work until I updated the baseURL to http://localhost:5173/api

Here is my MSW setup:

import { User } from '../../Store/RTK/userSlice'
import { rest } from 'msw'
import { setupServer } from 'msw/node'

export const handlers = [
  rest.get('http://localhost:5173/api/users', (_, res, ctx) => {
    const testUser: Partial<User> = {
      id: '1',
      username: 'test user'
    }

    return res(
      ctx.status(200),
      ctx.json([testUser])
    )
  }),

  rest.get('http://localhost:5173/api/auth', (_, res, ctx) => {
    const testAuthUser: Partial<User> = {
      id: '0',
      username: 'test auth user'
    }

    return res(
      ctx.status(200),
      ctx.json(testAuthUser)
    )
  })
]

export const server = setupServer(...handlers)

The url needs to match my authSlice's baseUrl, but it only works when I use the url http://localhost:5173/api/auth for both. Simply doing /api/auth does not work.

I assume this will be an issue when I deploy the app since I'll probably have to include an env variable or something to make the RTK Query work. Is there a way to make everything work with a baseUrl of /api?

In case relevant, here is my test:

it('sets the auth user', async () => {
      renderWithProviders(<HomeWithRouter />);

      const serverDataRegex = new RegExp(`test auth user`, 'i');
      
      const serverData = await screen.findByText(serverDataRegex)
      
      expect(serverData).toBeInTheDocument()
    })

Upvotes: 1

Views: 1161

Answers (2)

Joel Cheah
Joel Cheah

Reputation: 23

Adding to Lenz's answer, since I happen to use the exact same tools as you are and went through multiple Github discussions in Redux and MSW.

RTK baseQuery needs a absolute path as mentioned by Lenz:

const baseQuery = fetchBaseQuery({
  baseUrl: import.meta.env.VITE_API_BASE_URL, // Use environment variables for flexibility
  // Other config
});

Vite .env Configuration uses different file names for development, production and testing environment. Thought I'd include it because these were all part of the issues I encountered myself. For production you'd need a .env.production file

.env.development

VITE_API_BASE_URL=http://localhost:<some-port>
VITE_API_TIMEOUT=15000

.env.test

VITE_API_BASE_URL=http://localhost:<some-port>
VITE_API_TIMEOUT=15000

As for MSW Handlers, the latest version I'm using, and with jsdom environment, I am able to use relative paths in the handlers.

import { http, HttpResponse } from "msw";

export const handlers = [
  http.get("/api/data", () => {
    return HttpResponse.json({ message: "Mocked data retrieved successfully" });
  }),

  http.post("/api/submit", () => {
    return HttpResponse.json({ success: true });
  }),
];

Upvotes: 0

phry
phry

Reputation: 44276

No, it's not possible. If you make requests in a node environment, you cannot work with relative urls. There is no "current" url (which usually is your browser url bar), so it couldn't be relative to anything.

You will need an absolute url.

Upvotes: 0

Related Questions