Testing your API

Use the built-in test runner, and test the routes themselves.

A test is code that checks your code, so you can change things without fear. Here is the idea in a few lines. Change an expected value to see a failure.

Expected output
PASS 18% of 1000: got 180, expected 180
PASS 5% of 250: got 12.5, expected 12.5
PASS zero: got 0, expected 0
PASS rounds to paise: got 18, expected 18

Node has a test runner built in. Put tests in files ending in .test.js and run node --test.

Node.js
// gst.test.js
import { test } from "node:test";
import assert from "node:assert/strict";
import { gst } from "./gst.js";

test("adds 18% by default", () => {
  assert.equal(gst(1000), 180);
});

test("uses the rate it is given", () => {
  assert.equal(gst(250, 5), 12.5);
});

Test the routes

Node.js
// app.test.js
import { test } from "node:test";
import assert from "node:assert/strict";
import { app } from "./app.js";

test("an unknown job gives 404", async () => {
  const server = app.listen(0);
  try {
    const { port } = server.address();
    const res = await fetch(`http://localhost:${port}/api/jobs/999`);
    assert.equal(res.status, 404);
  } finally {
    server.close();
  }
});

Port 0 asks the system for any free port, so tests never clash with a server that is already running. This is why app.js builds the app and server.js only starts it.

  • Test the normal case.
  • Test bad input: missing fields, wrong types, very long text.
  • Test a visitor who is not signed in, and one signed in as a different user.
  • Test what happens when the database or another API fails.

๐Ÿ”ฌ Try it: all green, nothing tested โ†’

โ† Sign-in and permissionsNode.js quick reference โ†’