Using Mock Service Worker with Vitest and fetch
The JavaScript ecosystem has a lot to offer when it comes to testing. With the recent addition of Vitest we get the performance and convenience features of Vite for testing too. Mock Service Worker is an excellent mocking solution for mocking network requests in the browser and Node.js.
Let’s see how we can combine the power of both tools to write awesome tests.
Polyfilling fetch
On the surface of it, using Mock Service Worker and Vitest together is straightforward. However, there is one problem: we likely use fetch
in our application to fetch data. And we want to use Mock Service Worker to mock those requests. But Vitest runs in a Node.js context, and there is no fetch
in a Node.js environment (yet, it’s coming). So if you run your Mock Service Worker enabled tests in Vitest, and your request handlers do not seem to have any effect, this is the problem.
After we’ve set up Vitest and Mock Service Worker according to the documentation of those projects, there is one other thing we have to do: We need to add a polyfill for fetch
for our tests.
First, we install the cross-fetch
package:
npm install --save-dev cross-fetch
And then we add it to our Vitest setup file (create it if you don’t have one yet):
// tests/setup.ts
import { afterAll, afterEach, beforeAll } from "vitest";
import { fetch } from "cross-fetch";
import { server } from "./utils";
// Add `fetch` polyfill.
global.fetch = fetch;
beforeAll(() => server.listen({ onUnhandledRequest: `error` }));
afterAll(() => server.close());
afterEach(() => server.resetHandlers());
This is my setup.ts
file. You can see that I also start and close the Mock Service Worker server here. If you don’t had a setup file yet, you also need to tell Vitest about it.
// vitest.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
// ...
setupFiles: ["./tests/setup.ts"],
},
});
And that’s it! Now mocking network requests made with fetch
should work as expected.