Skip to main content
On this page

Migrating from Jest

Most Jest suites translate to deno test without rewriting test logic: the node:test module provides the same describe/it structure, and the standard library ships an expect with the matchers you already use. What changes is a handful of imports and how the runner is configured.

The same test, in Deno Jump to heading

A typical Jest test needs only new imports:

cart.test.ts
import { beforeEach, describe, it } from "node:test";
import { expect, fn } from "jsr:@std/expect";

describe("shopping cart", () => {
  let cart: string[];

  beforeEach(() => {
    cart = [];
  });

  it("starts empty", () => {
    expect(cart).toHaveLength(0);
  });

  it("notifies a listener", () => {
    const onAdd = fn();
    cart.push("apple");
    onAdd(cart.length);
    expect(onAdd).toHaveBeenCalledWith(1);
  });
});
>_
$ deno test cart.test.ts
ok | 1 passed (2 steps) | 0 failed (13ms)

Unlike Jest, nothing is injected as a global: describe, it, expect, and the hooks are explicit imports, so each file states what it uses. Tests written against node:test also keep working in Node.js itself.

What maps to what Jump to heading

Jest Deno
describe, it, beforeEach, … node:test (or @std/testing/bdd)
expect(...) matchers jsr:@std/expect
jest.fn() fn() from jsr:@std/expect
jest.spyOn(obj, "m") spy/stub from @std/testing/mock
toMatchSnapshot() assertSnapshot
jest.useFakeTimers() FakeTime
npx jest deno test
npx jest --watch deno test --watch
npx jest -t "name" deno test --filter "name"

Translate the configuration Jump to heading

Jest configuration mostly disappears: TypeScript, JSX, and ES modules work without transforms, so ts-jest, babel-jest, and transform entries have no equivalent to migrate. File selection moves into deno.json:

deno.json
{
  "test": {
    "include": ["src/**/*.test.ts"],
    "exclude": ["src/fixtures/"]
  }
}

Module mocks Jump to heading

There is no equivalent of jest.mock("./module"), because module records are immutable in Deno. Tests that rely on it migrate to one of:

  • dependency injection: pass the collaborator in, and hand the test a spy or stub,
  • stubbing the object the module exposes, with stub from @std/testing/mock.

This is usually the only part of a migration that requires touching the code under test.

Keep npm packages where it helps Jump to heading

Test helpers from npm keep working through npm: specifiers, for example npm:@testing-library/dom for DOM assertions (see Use Testing Library with Deno). The test runner itself is the part you migrate.

For runner flags, reporters, and coverage, see the deno test reference.

Did you find what you needed?

Edit this page
Privacy policy