Build Elevate

Jest Presets

Unified Jest testing configuration for Node.js workspaces with consistent test execution across the monorepo

Overview

@workspace/jest-presets provides unified Jest configuration for Node.js workspaces in the monorepo. This ensures consistent test execution and coverage reporting for API and server-oriented packages.

Features

  • Shared Presets - Consistent testing configuration for Node.js environments
  • Node.js Preset - For server-side, API, and package testing
  • TypeScript Support - Built-in TypeScript test support via ts-jest
  • Coverage Reporting - Integrated coverage tracking

Project Structure

packages/jest-presets/
├── node/
│   └── jest-preset.js   # Node.js/server testing configuration
├── package.json         # Dependencies
└── README.md           # Package documentation

Available Presets

Node.js Preset

For server-side code, Express APIs, backend packages, and utilities:

// jest.config.js
const preset = require("@workspace/jest-presets/node");

module.exports = preset;

Configuration includes:

  • Jest environment: node
  • TypeScript and TSX support via ts-jest
  • Path alias mapping for @workspace/utils packages
  • Module extensions: .ts, .tsx, .js, .jsx, .json, .node
  • Ignores test fixtures, node_modules, and dist directories

Usage

Web workspaces use Vitest via Vitest Presets. Keep Jest presets for API/server workspaces unless you are intentionally migrating test runners.

Running Tests

Run all tests across the monorepo:

pnpm test

Run tests for a specific workspace:

pnpm test --filter=auth
pnpm test --filter=db

Watch mode for development:

pnpm test -- --watch

Coverage Reports

Generate coverage reports:

pnpm test

Coverage output goes to the coverage/ directory in each workspace.

File Structure for Testing

Recommended test file organization:

src/
├── utils/
│   ├── format.ts
│   └── format.test.ts
├── services/
│   ├── api.ts
│   └── api.test.ts
└── helpers/
    ├── helpers.ts
    └── helpers.test.ts

Writing Tests

Example: Utility Function Test

import { capitalize } from "@workspace/utils/helpers";

describe("capitalize", () => {
  it("capitalizes the first letter", () => {
    expect(capitalize("hello")).toBe("Hello");
  });

  it("handles empty strings", () => {
    expect(capitalize("")).toBe("");
  });
});

Example: API Function Test

import { getUserById } from "@/services/user";

describe("getUserById", () => {
  it("returns user data", async () => {
    const user = await getUserById("123");
    expect(user.id).toBe("123");
  });

  it("throws on invalid ID", async () => {
    await expect(getUserById("invalid")).rejects.toThrow();
  });
});

Customizing Jest Configuration

To customize Jest for a specific workspace, extend the preset:

const preset = require("@workspace/jest-presets/node");

module.exports = {
  ...preset,
  testPathIgnorePatterns: ["node_modules", "dist/"],
  collectCoverageFrom: [
    "src/**/*.{ts,tsx}",
    "!src/**/*.d.ts",
    "!src/**/*.test.{ts,tsx}",
  ],
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 70,
      lines: 70,
      statements: 70,
    },
  },
};

Key Scripts

Run from the monorepo root:

CommandPurpose
pnpm testRun all workspace tests

Run from individual workspaces (e.g., apps/api, packages/utils):

CommandPurpose
pnpm testRun tests with coverage reporting
pnpm test -- --watchWatch mode for development

Best Practices

Write Descriptive Test Names

// ✓ Good
it("returns user when ID is valid", () => {
  // implementation
});

// ✗ Vague
it("works", () => {
  // implementation
});

Test Edge Cases

describe("calculateTotal", () => {
  it("sums positive numbers", () => {
    expect(calculateTotal([1, 2, 3])).toBe(6);
  });

  it("handles empty array", () => {
    expect(calculateTotal([])).toBe(0);
  });

  it("handles negative numbers", () => {
    expect(calculateTotal([1, -2])).toBe(-1);
  });
});

Use Async/Await

// ✓ Good
it("fetches user data", async () => {
  const user = await fetchUser(123);
  expect(user.name).toBe("John");
});

// ✓ Also good with done callback
it("fetches user data", (done) => {
  fetchUser(123).then((user) => {
    expect(user.name).toBe("John");
    done();
  });
});

Troubleshooting

Tests Not Found

# Ensure test files follow naming convention
# Should be *.test.ts or *.spec.ts

# Check jest.config.ts includes correct patterns

TypeScript Errors

# Regenerate types
pnpm check-types

# Clear Jest cache
pnpm test --clearCache

Coverage Thresholds

If tests pass but coverage thresholds fail, add more test cases for untested code paths.

For more details on Jest configuration, see the Jest documentation.

On this page