Supertest: Test Node.js APIs Without the Boilerplate
Supertest lets you test your Node.js API without running a separate server. Use it in Jest or Mocha to make requests to your routes and assert on responses. The footgun: since it's in-process, state can leak between tests if not reset properly.
WHY IT EXISTS: Testing an HTTP API often requires spinning up a server, choosing a port, making HTTP requests with a client like axios or fetch, and then tearing it all down. This adds significant boilerplate and complexity to your test suite. Supertest was created to eliminate this friction for Node.js applications.
THE MENTAL MODEL: Think of Supertest as a direct line to your web application's router, but one that speaks the language of HTTP. Instead of manually starting your server and sending a fetch request to localhost:3000, you give your app object directly to Supertest. It simulates the entire HTTP request-response cycle in-memory, making tests faster and simpler to write.
HOW IT WORKS: You provide Supertest's request() function with your Node.js app instance (e.g., an Express app object). Supertest automatically binds the app to an ephemeral (temporary, random) port if it's not already listening. It then uses its underlying library, Superagent, to construct and send an HTTP request to that in-process server. You can chain .expect() calls to assert on the response status, headers, and body. The test completes in a final callback or by returning a promise that resolves with the response.
WHEN TO USE IT: Use Supertest for integration testing your API endpoints in a Node.js environment. It's perfect for verifying that your routes, middleware, and controllers work together as expected. For example, testing that a POST /users request with valid data returns a 201 Created and that a request with invalid data returns a 400 Bad Request.
WHEN NOT TO USE IT: Avoid Supertest for true end-to-end (E2E) tests that need to simulate a full network environment with a separate, deployed server. It's also not the right tool for pure unit tests of individual functions (e.g., a single data transformation utility), where you don't need the HTTP layer at all.
ONE CANONICAL EXAMPLE: Imagine an Express app with a single endpoint: app.get('/user', (req, res) => res.status(200).json({ name: 'john' })). To test this, you import request from Supertest and pass it your app. You can then chain methods to describe the test: request(app).get('/user').expect('Content-Type', /json/).expect(200). This single line sends a GET request to /user and asserts that the response has a JSON content type and a 200 status code, failing the test if either is untrue.
Read the original → github.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.