Testing a Node API
💻 Node.jsWrite automated tests for routes and logic with the built-in node:test runner.
A manual test proves a route worked once. An automated test proves it still works after every change.
- Write a unit test.
- Test an HTTP route.
- Run tests with npm test.
The Built-in Runner
Node includes a test runner. No extra package is required for simple tests. Save the file and run node --test.
import { test } from "node:test";
import assert from "node:assert/strict";
import { add } from "./maths.js";
test("adds two numbers", () => {
assert.equal(add(2, 3), 5);
});Test the Logic First
Extract validation and calculation into pure functions. Pure functions are fast to test and do not need a running server.
Test a Route
Start the app on a random port, send a request, assert the status and body, then close the server. Keep each test independent.
import { test } from "node:test";
import assert from "node:assert/strict";
import { app } from "./app.js";
test("GET /health returns ok", async () => {
const server = app.listen(0);
const { port } = server.address();
const response = await fetch(`http://localhost:${port}/health`);
const body = await response.json();
assert.equal(response.status, 200);
assert.equal(body.status, "ok");
server.close();
});Practice
- Write a test for a function that formats a name.
- Test that a missing student id returns 404.
- Add npm test to package.json.
Hands-on exercise
Write tests for a function grade(score) that returns A, B, C or F.
1. Test a score of 72 returns A.
2. Test 64 returns B.
3. Test 41 returns F.
Run them with node --test.
Recap
Automated tests protect behaviour. Test pure logic first, then cover routes and the failure cases.
Example
import { test } from "node:test";
import assert from "node:assert/strict";
import { add } from "./maths.js";
test("adds two numbers", () => {
assert.equal(add(2, 3), 5);
});
Exercises
1. Test a score of 72 returns A.
2. Test 64 returns B.
3. Test 41 returns F.
Run them with node --test.
Expected Output
Three passing tests.