The MSW handler successfully intercepts the request, yet an Axios network error still persists

I'm feeling a bit stuck - I've gone through numerous posts here discussing the combination of Axios and MSW [1] [2] [3], but I still can't quite pinpoint where my mistake lies.

My goal is to utilize MSW to intercept network requests made by Axios and inject responses for testing purposes.

Here's the code snippet:

Testing file (this will fail, as I'm still trying to get it working properly)-

/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { jobsDashboardResponse } from "../../../tests/mocks/msw/handlers"
import { server as mswServer } from "../../../tests/mocks/msw/server"
import { bacalhauAPI } from "../bacalhau"

// Enable request interception.
beforeAll(() => mswServer.listen())

// Reset handlers so that each test could alter them
// without affecting other, unrelated tests.
afterEach(() => mswServer.resetHandlers())

// Don't forget to clean up afterwards.
afterAll(() => mswServer.close())

describe("Basic fetch of mocked API", () => {
    it("should GET /orchestrator/jobs", async () => {
        const jobsResponse = { a: 2 }

        mswServer.use(jobsDashboardResponse)
        mswServer.listHandlers()

        const jobs = await bacalhauAPI.listJobs()

        expect(jobs).toEqual(jobsResponse)
    })
})

BacalhauAPI server ts:

import axios, { AxiosInstance } from "axios"
import {
  JobListRequest,
} from "../helpers/jobInterfaces"

class BacalhauAPI {
  apiClient: AxiosInstance

  constructor(baseURL: string) {
    this.apiClient = axios.create({
      baseURL,
      headers: {
        "Content-Type": "application/json",
      },
    })
  }

  async listJobs(labels?: string[], nextToken?: string): Promise<JobsResponse> {
    try {
      const params: JobListRequest = {
        order_by: "created_at",
        reverse: true,
        limit: 10,
        labels: labels ? `env in (${labels.join(",")})` : undefined,
        next_token: nextToken,
      }
      const response = await this.apiClient.get("/orchestrator/jobs", {
        params,
      })
      return response.data as JobsResponse
    } catch (error) {
      console.error("An error occurred while listing jobs:", error)
      throw error
    }
  }

}

function getAPIConfig(
  property: "host" | "port" | "base",
  defaultValue: string
): string {
  const declared = document
    .querySelector(`link[rel=api-${property}]`)
    ?.getAttribute("href")
  const useDefault =
    declared === undefined ||
    declared?.match(/\{{2}/) ||
    declared === "" ||
    declared === null
  return useDefault ? defaultValue : declared || ""
}

const host = getAPIConfig("host", document.location.hostname)
const port = getAPIConfig("port", "1234")
const base = getAPIConfig("base", "api/v1")
export const bacalhauAPI = new BacalhauAPI(
  `${document.location.protocol}//${host}:${port}/${base}`
)

msw handlers:

import { http, HttpResponse, RequestHandler, RequestHandlerOptions } from "msw";
import { TestData } from "../../basic/msw.tests";

export const jobsDashboardResponse = http.get('http://localhost:1234/api/v1/orchestrator/jobs', ({ cookies }) => {
  // Placeholders for messing around with cookies
  const { v } = cookies

  return HttpResponse.json(v === 'a' ? { foo: 'a' } : { bar: 'b' })
})

export const handlers: RequestHandler<any, any, any, RequestHandlerOptions>[] = [jobsDashboardResponse]

msw server:

import { setupServer } from "msw/node"
import { handlers } from "./handlers"

export const server = setupServer(...handlers)

The issue at hand:

  console.error
    An error occurred while listing jobs: AxiosError {
      message: 'Network Error',
      name: 'AxiosError',
      code: 'ERR_NETWORK',
      config: {
        transitional: {
          silentJSONParsing: true,
          forcedJSONParsing: true,
          clarifyTimeoutError: false
        },
        adapter: [ 'xhr', 'http' ],
        transformRequest: [ [Function: transformRequest] ],
        transformResponse: [ [Function: transformResponse] ],
        timeout: 0,
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        maxBodyLength: -1,
        env: { FormData: [Function], Blob: [class Blob] },
        validateStatus: [Function: validateStatus],
        headers: Object [AxiosHeaders] {
          Accept: 'application/json, text/plain, */*',
          'Content-Type': null
        },
        baseURL: 'http://localhost:1234/api/v1',
        params: {
          order_by: 'created_at',
          reverse: true,
          limit: 10,
          labels: undefined,
          next_token: undefined
        },
        method: 'get',
        url: '/orchestrator/jobs',
        data: undefined
      },

      // The rest of the error logs are cut off for brevity...
    }

When I console.log or debug, it's evident that the MSW handler is being triggered. So, what's causing this issue?

[1] Reactjs: MSW mock handlers failing with Error "Network request failed"

[2] FETCH_ERROR "TypeError [ERR_INVALID_URL]: Invalid URL" for requests made in tests

[3] Jest returns "Network Error" when doing a mock request with axios and msw

Answer №1

After some investigation, I've figured out the issue. It seems to be related to undici, as mentioned in this post:

https://github.com/mswjs/msw/discussions/1915

In short, the solution is to downgrade undici to version v5.26.2.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A $scope variable cannot be accessed inside the callback function of a resource get call

Unable to access the $scope variable, encountering issues with it not working correctly. A resource has been defined: squashApp.factory('CourtsService', function($resource) { return $resource('/api/court/:num', {num: '@num&apos ...

Extracting cache-control header value from server response

Looking to interpret the cache-control header response in order to utilize it for caching the API response. Here is an example of the response headers: {"x-backside-transport":"OK OK","connection":"close","transfer-encoding":"chunked","access-control-all ...

Utilizing *ngIf for Showing Elements Once Data is Completely Loaded

While working on my Angular 2 app, I encountered an issue with the pagination UI loading before the data arrives. This causes a visual glitch where the pagination components initially appear at the top of the page and then shift to the bottom once the data ...

Jasmine unfortunately is not compatible with Selenium WebDriver

I am currently attempting to create a basic UI test using Jasmine and selenium webdriver. Unfortunately, I have encountered some difficulties in getting it to function properly. Here is the setup I am working with: node v6.6.0 [email protected] (in ...

Troubleshooting issues when testing Angular services using Jasmine and Chutzpah

I've been facing some challenges while attempting to test my AngularJs services with Jasmine as I encounter various errors consistently. In an effort to troubleshoot, I decided to create a simple Sum service for testing purposes but unfortunately, the ...

The incorrect date selection made by the Datepicker feature in the Vue / Buefy component

Currently, I am utilizing Vue / Buefy as a datepicker in the form on a specific page (2nd step). You can find the page here: An issue has arisen where the date of birth input is sometimes recorded inaccurately. For instance, the user selects June 5th, 197 ...

An issue arose when attempting to access a Mashape web service with JavaScript

I am attempting to make use of a Mashape API with the help of AJAX and JavaScript. Within my HTML, I have a text area along with a button: <div> <textarea id="message" placeholder="Message"> </textarea> <br><br> ...

Steps for opening a modal in a react native application when a button is clicked

Exploring the realm of react native, I face a challenge in triggering a modal on button click. I've attempted to implement the following code snippet to achieve this goal:- openHeaderModal = () => { <ModalDropdown options={["H1", "H ...

I am interested in rotating the yAxes scaleLabel in Angular using Chart.js

I have a vertical chart that I want to rotate horizontally. Unfortunately, there are no maxRotation and minRotation parameters for the yAxes, so I'm unsure of how to achieve this rotation. Although I found a similar question, I struggled to implement ...

Preventing incomplete file uploads (through FTP) while retrieving the latest file using ajax and PHP

Yes, the title of this may seem unusual, but there's a reason for it. In my setup, I have a camera linked to a laptop. Through Remote Shooting, when a photo is captured by the photographer, it gets stored in a folder on the laptop's hard drive. ...

A guide to accessing a prop from a child component in ReactJS

Currently, I am delving into React.js and experimenting with integrating the pokeAPI into a website project. One of the widgets I am working on involves displaying multiple pokemons along with their respective statistics. To achieve this, I have set up a ...

Display a preview of the image when hovering over a dynamically generated dropdown menu

I have come across numerous posts where hovering over an item in the dropdown bar reveals an image. However, all of these posts have hardcoded the items in the dropdown within the HTML. I am dynamically generating the dropdown items using JavaScript and I ...

What is the method for ending the mouseleave effect?

Clicking on the box will trigger a change in the text on mouseleave. Clicking on the button will also cause another change in the text. How can we revert the text back to its original position after removing the effects triggered by clicking the button and ...

Leveraging the Meteor Framework for Application Monitoring

Exploring the potential of utilizing Meteor Framework in a Monitoring Application. Scenario: A Java Application operating within a cluster produces data, which is then visualized by a Web Application (charts, etc.) Currently, this process involves using ...

Exploring the utilization of functions beyond module exports

Striving to clearly communicate my intentions, please feel free to ask if anything is unclear. Within a file named www, I am configuring my socket as follows: var server = http.createServer(app); var io = require('socket.io')(server); require(& ...

Issues with DJS Leaderboard Rankings display malfunction

I've been working with this leaderboard command for some time now. I wanted to enhance user experience by displaying the rank of users if they are not in the top 10 based on their coin count. However, I encountered a problem when trying to add this f ...

Is it possible to refresh a div on one .aspx page using content from another .aspx page?

Just beginning my journey with asp.net and currently tackling a project that involves two .aspx pages. Events.aspx: This page is where the site admin can update upcoming events and webinars using an available panel to input event title, date, information ...

What is the best method for achieving a pristine white floor with subtle shadows?

I'm struggling to achieve a white floor with shadows on it, but all I end up with is a lightgray floor with very thin shadow. Here's my floor and light configuration: const ModelSceneEnvironment = () => { return ( <> {/* Lig ...

BufferGeometry lines in THREE.js are failing to render when their starting point is outside the view of the camera

Currently, I am in the process of developing a trace-line function for a visualization project that involves transitioning between different time step values. However, I have encountered an issue while using THREE.js's BufferGeometry and the setDrawRa ...

Choose a specific example using the class name in nicEdit

Is there a way to select an instance using nicEdit based on its class name rather than just its id? For example: <div class="myInstance1"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed magna dolor, faucibus ac, iaculis non, cursus et ...