Skip to content

Connect MSW

MSW intercepts HTTP at the network boundary. Your HttpClient uses the Fetch API, so no code changes are required in the client: point baseUrl (and paths) at URLs your handlers match, and fetch is satisfied by MSW instead of a real server.

This package does not ship MSW; add it to your app or test project:

bash
npm install msw -D
bash
pnpm add msw -D
bash
yarn add msw -D

When it needs

  • You want the real HttpClient / fetch path in tests (URL building, headers, formatters, interceptors), not a stubbed client.
  • You want one set of handlers for Node and for the browser (or Cypress / Playwright), with the same URL rules.
  • Your project already uses MSW for HTTP mocking and you want generated endpoints to plug into that setup.

Node.js (setupServer)

Use setupServer from msw/node so Node’s globalThis.fetch (and therefore HttpClient) is intercepted in the test process.

  1. Handlers — match the full URL the client will request (baseUrl + path, including query if you use it).

mswEndpointHandler wires an endpoint to MSW in one call; see mswEndpointHandler, mswEndpointResponse, and mswPathPattern if you build handlers by hand.

ts
import {
  mswEndpointHandler,
  mswEndpointResponse,
} from "mobx-tanstack-query-api/testing";

// `listFruits`, `createFruit`: your generated endpoints (GET/POST come from `params().method`).
export const handlers = [
  mswEndpointHandler(listFruits, () => ({
    items: ["apple", "banana"],
  })),
  mswEndpointHandler(createFruit, async ({ request }) => {
    const body = (await request.json()) as { name: string };
    return mswEndpointResponse(
      createFruit,
      { id: 1, name: body.name },
      { status: 201 },
    );
  }),
];
  1. Server lifecycle — register once per test file or globally via your runner’s setup file (e.g. Vitest setupFiles).
ts
import { setupServer } from "msw/node";
import { afterAll, afterEach, beforeAll } from "vitest";
import { handlers } from "./handlers";

const server = setupServer(...handlers);

beforeAll(() =>
  server.listen({
    onUnhandledRequest: "error", // fail fast if a request has no handler
  }),
);
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
  1. Use your real HttpClient (or generated API module) as in production.
ts
import { HttpClient } from "mobx-tanstack-query-api";

const httpClient = new HttpClient({
  baseUrl: "https://api.example.com",
});

const res = await httpClient.request({
  path: "/api/v1/fruits",
  method: "GET",
  format: "json",
});

expect(res.data).toEqual({ items: ["apple", "banana"] });

Generated endpoints call the same HttpClient.request path, so endpoint.request(...) and EndpointQuery / EndpointMutation flows work as long as the resolved URL matches a handler.

Tips

  • Default status codes — see testingDefaults; override per response with init.status where applicable.
  • Absolute URLs — MSW matches the URL fetch receives. If baseUrl is https://api.example.com and the path is /users/1, the handler pattern should be https://api.example.com/users/1 (or use a path predicate / new URL(request.url) inside the resolver for flexibility).
  • Unhandled requestsonUnhandledRequest: "error" catches typos in baseUrl or paths early; relax to "warn" while migrating.
  • Per-test overridesserver.use(http.get(...)) after setupServer adds or replaces handlers for a single test; resetHandlers() clears them in afterEach.

Browser and E2E

For browser tests (e.g. Cypress, Playwright, or Vite-powered dev), MSW runs in the Service Worker (setupWorker). The same handler URLs apply; ensure the app’s HttpClient baseUrl matches what the worker intercepts (often your dev server origin or a dedicated API host).

When to use MSW vs package Vitest helpers

ApproachBest for
MSWExercising the full HttpClient stack (headers, buildUrl, formatters, interceptors), sharing handlers between browser and Node, or teams already standardized on MSW.
Testing helpersFast unit tests without MSW (Vitest-first), typed HttpResponse via mockHttpClientRequest* / mockEndpointRequest*, no global listener.

You can mix both: MSW for integration-style suites and Vitest helpers for narrow endpoint logic.

Further reading

Released under the MIT License.