Module 46: Backend Testing

Lesson 3 of 5 · 15–25 minutes

API tests with Supertest

🏠The everyday picture

A mystery shopper who walks in through the front door like any customer, places real orders, and reports exactly what happened at the counter.

📘What it really is

import request from "supertest";
import { app } from "../src/app.ts";

it("refuses to list enquiries when signed out", async () => {
  const res = await request(app).get("/enquiries");
  expect(res.status).toBe(401);
});

it("creates an enquiry with valid data", async () => {
  const agent = request.agent(app);                 // keeps cookies, like a browser
  await agent.post("/auth/sign-in").send({ email: "staff@test.in", password: "test-password-123" });
  const res = await agent.post("/enquiries").send(validEnquiry);
  expect(res.status).toBe(201);
  expect(res.body.status).toBe("new");
});

it("returns field errors for invalid data", async () => {
  const res = await signedInAgent.post("/enquiries").send({ name: "" });
  expect(res.status).toBe(422);
  expect(res.body.fields.email).toBeDefined();
});

🖱️Try it

Install supertest. Write API tests for: 401 when signed out; sign-in success and failure; create (201), invalid create (422), get unknown (404); and one test that a 500 response contains no stack trace. Run them with the rest.

✅Quick check

Why can Supertest test the app without starting a server?

Show the answer

It uses the exported app directly, which is kept separate from the code that listens on a port.

What does request.agent(app) do that request(app) doesn't?

Show the answer

It keeps cookies between requests, like a browser, so you can sign in and then make signed-in requests.

← PreviousUnit tests for services
ProLearners Assist