Node.js testing using Mocha and Supertest
Written By: Avinash Malhotra
Updated on
Testing is a very important part of any backend application. It helps you catch bugs early and makes sure your application and APIs work as expected even after changes. In Node.js, Mocha and Supertest are two popular tools used together for API testing.
Mocha is a feature-rich JavaScript test framework running on Node.js and the browser, while Supertest is a library for testing HTTP requests and responses.
This article explains how to use Mocha and Supertest to test your application and APIs and how to use them with a real example.
What is Mocha?
Mocha is a testing framework for Node.js. It gives structure to your tests and helps you write them in an organized way. Mocha provides a rich set of features for testing JavaScript applications, including support for asynchronous testing, hooks, and various reporting options.
What does Mocha do?
describe()to group test casesit()to define individual test cases- Clear pass/fail output in the terminal
Mocha does not test APIs by itself. It only runs and manages tests.
Install Mocha
To install Mocha globally, run the following command:
To install Mocha as a development dependency in your project, run:
For macOS and Linux
Run Mocha
To run Mocha, create a folder named `test` in your project directory and add your test files there, let's say named test.js:
Add mocha in package.json
You can also add a test script in your package.json file to run Mocha:
"scripts": {
"test": "mocha"
}
Now you can run your tests using npm:
Supertest
Supertest is a library that provides a high-level abstraction for testing HTTP APIs. It allows you to make requests to your API and assert the responses in a clean and readable way.
Install Supertest
Install Supertest on macOS and Linux
Why use Supertest with Mocha?
Supertest is designed to work seamlessly with Mocha, providing a clean and expressive way to test HTTP APIs. It allows you to make requests to your API endpoints and assert the responses in a readable and maintainable way.
- Easy to learn and use
- Fast API testing
- Works well with Express
- Helps avoid breaking APIs in production
- Good for real-world backend projects
Best Practices
- Keep tests inside a test folder
- Test both success and failure cases
- Do not start the server in test files
- Write small and clear test cases
- Run tests before pushing code
- Use descriptive test names
- Organize tests by feature or module
Example of Mocha and Supertest
Let's create a simple Express application and write tests for its API using Mocha and Supertest.
Create a Simple Express Application
/* app.js */
import express from "express";
const app = express();
app.use(express.json());
app.get("/", (req, res) => {
res.status(200).send("Hello World");
});
app.get("/api", (req, res) => {
res.status(200).json({ message: "API is working" });
});
export default app;
/* server.js */
import app from "./app.js";
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Write Tests with Mocha and Supertest
Now let's write tests for our API endpoints using Mocha and Supertest. Note that Mocha doesn't include assertion libraries by default, so we'll use Node.js built-in assert module for simplicity, or you can install Chai for more expressive assertions.
/* test/test.js */
import request from "supertest";
import app from "../app.js";
import assert from "assert";
describe("API Tests", () => {
it("should return Hello World on root endpoint", async () => {
const response = await request(app).get("/");
assert.strictEqual(response.status, 200);
assert.strictEqual(response.text, "Hello World");
});
it("should return API working message", async () => {
const response = await request(app).get("/api");
assert.strictEqual(response.status, 200);
assert.deepStrictEqual(response.body, { message: "API is working" });
});
});
Run Tests
To run the tests, use the following command:
The tests will run and display the results in the terminal. You should see output indicating which tests passed or failed.
Additional Tips
- Use
beforeEachandafterEachhooks in Mocha to set up and tear down test data. - For more advanced assertions, install Chai:
npm install --save-dev chaiand useexpectsyntax. - Consider using test coverage tools like Istanbul (nyc) to measure how much of your code is tested.
- Run tests in CI/CD pipelines to ensure code quality before deployment.
Conclusion
Mocha and Supertest are powerful tools for testing Node.js applications. Mocha provides a flexible testing framework, while Supertest simplifies HTTP API testing by offering an easy-to-use interface for making requests and asserting responses.
By combining these two tools, you can create comprehensive test suites that ensure your APIs work as expected and help catch bugs early in the development process. Remember to write tests for both success and error scenarios, and integrate testing into your development workflow for better code quality.