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