0

i'm trying to make a mock service worker to a simple API request like that: /src/api/Sectors.js

export const getSectors = async (token)=>{
    const requestOptions = {
        method: "GET",
        headers: {
            "Content-Type": "application/json",
            Authorization: "Bearer " + token,
        },
    };
    try{
        const response = await fetch("/api/sector/list", requestOptions);
        if(!response.ok){
            return{error:`Request failed with status ${response.status}`}
        }else{
            const data = await response.json();
            return data;
        }
    } catch (error){
        return{ error : "Request failed"}
    }
};

My setup files are that:

jest.setup.js:

import "@testing-library/jest-dom";
import {server} from 'src/mocks/server.js';

beforeAll(() => {
  server.listen()
  console.log('server listening')
});

afterEach(() => server.resetHandlers());

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

jest.config.js:

const TEST_REGEX = "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|js?|tsx?|ts?)$";

module.exports = {
  testRegex: TEST_REGEX,
  transform: {
    // "^.+\\.tsx?$": "ts-jest",
    "^.+\\.jsx?$": "babel-jest",
    // "^.+\\.mjs$": "babel-jest",
  },
  testPathIgnorePatterns: ["<rootDir>/build/", "<rootDir>/node_modules/", "<rootDir>/dist/"],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
  moduleNameMapper: {
    "^~(.*)$": "<rootDir>/src/$1"
  },
  modulePaths: ["<rootDir>"],
  testEnvironment: "node",
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
}

my setup for MSW is:

/src/mocks/handlers.js:

import { rest } from "msw";

export const handlers = [
    rest.get("/api/sector/list", (req, res, ctx) => {
    console.log('api sector list')
    const token = req.headers.get("Authorization");

    if (!token) {
      return res(
        ctx.status(401),
        ctx.json({ error: "Authorization token is missing" })
      );
    }

    return res(
      ctx.status(200),
      ctx.json([
        { id: 1, name: "Sector 1" },
        { id: 2, name: "Sector 2" },
      ])
    );
  }),
]

/src/mocks/server.js:

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

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

and my test is:

/tests/Sectors.test.js:

import { getSectors } from 'src/api/Sectors';
  it("should fetch sectors successfully", async () => {
    const token = "fakeToken";
    const sectors = await getSectors(token);

    expect(sectors).toEqual([
      { id: 1, name: "Sector 1" },
      { id: 2, name: "Sector 2" },
    ]);
  });

on date more the console log in handrels never prints, i asume thar mws never intercepts the api calls.

Wiskani
  • 9
  • 2

1 Answers1

1

I resolved the issue by including the "fetch" function in my test environment using the "whatwg-fetch" library:

import 'whatwg-fetch';
import '@testing-library/jest-dom';
import { server } from './src/mocks/server';

beforeAll(() => {
  server.listen();
  console.log('Server is listening...');
});

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

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

By importing "whatwg-fetch", I was able to use the "fetch" function to make HTTP requests in my React component. This library provides a consistent and modern implementation of the Fetch API for browsers that do not natively support it, ensuring that my application can make HTTP requests in a reliable and consistent way across different environments.

Wiskani
  • 9
  • 2
  • This is the correct solution. When testing code that relies on `fetch` in Node versions that don't ship fetch, always include a polyfill. Alternatively, consider migrating to newer Node (18 and higher) that ships with the global Fetch API by default. – kettanaito May 28 '23 at 10:45