Once you have a worker set up, you probably want to write tests for it. In this guide I will show how to write tests for outbound fetch() requests using vitest and miniflare. Originally I used the following guide to get the tests working but it seems not everything is included within the guide that may be obvious for first time Worker developers.

https://miniflare.dev/testing/vitest

Setup

Install Vitest

$ npm install -D vitest-environment-miniflare vitest

If you are not using service bindings you can use the following vitest.config.ts file:

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "miniflare",
  },
})

Finally use the following to enable Typescript support and type checking

{
  "compilerOptions": {
    ...
    "types": [
      "@cloudflare/workers-types",
      "vitest-environment-miniflare/globals" // add this line
    ]
  }
}

Minimum Worker Example

To be able to test a worker I had to use either a Service Worker format or have a handle() function that manipulated the request which was then called from the Module Worker. Here is an example worker

export default {
	async fetch(
		request: Request,
	): Promise<Response> {
		return  await handleRequest(request)
	},
};

async function handleRequest(request: Request): Promise<Response> {
	const response =  await fetch(request)
	const newResponse = new Response(response.body, response);
	newResponse.headers.set("x-new-header", "hello world")
	return newResponse
}

This will simply makes a request to what was passed in, adds a new header and then returns the response.

Writing Tests

This can now be tested using the following

import { expect, it } from "vitest";
import { handleRequest } from ".";

const describe = setupMiniflareIsolatedStorage();

describe("Worker", () => {
  it("should return Mocked response", async () => {
    const fetchMock = getMiniflareFetchMock();
    fetchMock.disableNetConnect();

    const origin = fetchMock.get("https://example.com");
    origin
      .intercept({ method: "GET", path: "/thing" })
      .reply(200, "Mocked response!");

	const request = new Request("https://example.com/thing");

	// act
    const response = await handleRequest(request);

	// assert
    const text = await response.text();
    expect(text).toMatchInlineSnapshot(`"Mocked response!"`);
    const newHeader = response.headers.get("x-new-header");
	expect(newHeader).toEqual("hello world")
  });
});

The first lines create the mock in miniflare for a request to example.com. Once this is done, we create a new request and execute it. Finally the assertions ensure that the mocked response was returned but also that the value of the new header is correct.

Summary

In this we’ve gone through how to unit test a worker that adds a header to a request.