Lesson 40 of 50 – API Testing in Node.js
80% Completed
80%

API Testing in Node.js

Learn how to test REST APIs using Postman, HTTP methods, request bodies, response status codes, and automated testing tools.

What is API Testing? API testing is the process of checking whether an API works correctly, returns the expected data, handles errors, and responds properly to different requests.

1. Why Is API Testing Important?

API testing helps developers verify that backend applications work correctly before connecting them to a frontend application.

  • Checks whether API endpoints work correctly.
  • Verifies the returned JSON data.
  • Checks HTTP status codes.
  • Tests GET, POST, PUT, PATCH, and DELETE requests.
  • Identifies validation and server errors.
  • Helps prevent bugs during application development.
Example: Before connecting a React application to a Node.js backend, you can test the backend API using Postman.

2. Popular API Testing Tools

Tool Purpose
Postman Send HTTP requests and inspect API responses.
Thunder Client Test APIs directly inside Visual Studio Code.
curl Send HTTP requests from the terminal.
Supertest Write automated tests for Node.js HTTP APIs.
Jest Run automated JavaScript tests and assertions.

3. Installing Postman

Postman is a popular application used to send HTTP requests and inspect API responses.

Steps to Start Using Postman
  1. Visit postman.com.
  2. Download and install Postman, or use a supported web workflow.
  3. Open Postman.
  4. Create a new HTTP request.
  5. Select an HTTP method.
  6. Enter your API URL.
  7. Click Send.
  8. Check the response body and status code.

4. Create a Sample Express API

First, create a simple Node.js project that we can test using Postman.

Install Express
npm init -y

npm install express

Create a file named server.js.

server.js – Student API
const express = require("express");

const app = express();

app.use(express.json());

let students = [
    { id: 1, name: "Rahul", course: "Node.js" },
    { id: 2, name: "Priya", course: "React" }
];

// GET all students
app.get("/students", (req, res) => {
    res.json(students);
});

// GET a single student
app.get("/students/:id", (req, res) => {
    const id = Number(req.params.id);

    const student = students.find(s => s.id === id);

    if (!student) {
        return res.status(404).json({
            message: "Student not found"
        });
    }

    res.json(student);
});

// POST a new student
app.post("/students", (req, res) => {
    const { name, course } = req.body;

    if (
        typeof name !== "string" ||
        !name.trim() ||
        typeof course !== "string" ||
        !course.trim()
    ) {
        return res.status(400).json({
            message: "Valid name and course are required"
        });
    }

    const newStudent = {
        id: Math.max(0, ...students.map(s => s.id)) + 1,
        name: name.trim(),
        course: course.trim()
    };

    students.push(newStudent);

    res.status(201).json(newStudent);
});

// PUT - Update student
app.put("/students/:id", (req, res) => {
    const id = Number(req.params.id);

    const student = students.find(s => s.id === id);

    if (!student) {
        return res.status(404).json({
            message: "Student not found"
        });
    }

    const { name, course } = req.body;

    if (
        typeof name !== "string" ||
        !name.trim() ||
        typeof course !== "string" ||
        !course.trim()
    ) {
        return res.status(400).json({
            message: "Valid name and course are required"
        });
    }

    student.name = name.trim();
    student.course = course.trim();

    res.json({
        message: "Student updated successfully",
        student: student
    });
});

// DELETE a student
app.delete("/students/:id", (req, res) => {
    const id = Number(req.params.id);

    const index = students.findIndex(s => s.id === id);

    if (index === -1) {
        return res.status(404).json({
            message: "Student not found"
        });
    }

    students.splice(index, 1);

    res.json({
        message: "Student deleted successfully"
    });
});

app.listen(5000, () => {
    console.log("Server running on port 5000");
});

Start your server using:

node server.js
Output: Server running on port 5000

5. Testing a GET Request

The GET method is used to retrieve data from an API.

GET Request in Postman

Method: GET

URL: http://localhost:5000/students

Steps: Select GET, enter the URL, and click Send.

Expected Response
[
    {
        "id": 1,
        "name": "Rahul",
        "course": "Node.js"
    },
    {
        "id": 2,
        "name": "Priya",
        "course": "React"
    }
]

Status Code: 200 OK

6. Testing a GET Request with an ID

You can retrieve a specific student by passing the student ID in the URL.

GET http://localhost:5000/students/1
Expected Response
{
    "id": 1,
    "name": "Rahul",
    "course": "Node.js"
}

Status Code: 200 OK

7. Testing a POST Request

The POST method is commonly used to create a new resource.

POST Request in Postman

Method: POST

URL: http://localhost:5000/students

Open Body → raw → JSON and enter:

{
    "name": "Aman",
    "course": "Python"
}

Click Send.

Expected Response
{
    "id": 3,
    "name": "Aman",
    "course": "Python"
}

Status Code: 201 Created

8. Testing a PUT Request

The PUT method is commonly used to replace or update a resource. Our sample API uses PUT to update the student's name and course.

PUT Request in Postman

Method: PUT

URL: http://localhost:5000/students/1

Enter this JSON body:

{
    "name": "Rahul Kumar",
    "course": "Full Stack Development"
}
Expected Response
{
    "message": "Student updated successfully",
    "student": {
        "id": 1,
        "name": "Rahul Kumar",
        "course": "Full Stack Development"
    }
}

Status Code: 200 OK

9. Testing a DELETE Request

The DELETE method is used to remove a resource.

DELETE Request in Postman

Method: DELETE

URL: http://localhost:5000/students/2

Expected Response
{
    "message": "Student deleted successfully"
}

Status Code: 200 OK

Note: This API stores data in a JavaScript array. All changes are lost when the server restarts. Later lessons will explain how to connect APIs to databases.

10. Important HTTP Status Codes

Status Code Meaning Example
200 OK Successful GET or PUT request.
201 Created A new student was created.
204 No Content Successful request with no response body.
400 Bad Request Invalid student data.
401 Unauthorized Authentication is required or invalid.
403 Forbidden The client lacks permission.
404 Not Found Student ID does not exist.
500 Internal Server Error Unexpected server-side failure.

11. Testing Error Responses

A good API should return useful error responses when a request is invalid.

Example 1: Student Not Found
GET http://localhost:5000/students/999
Expected Response
{
    "message": "Student not found"
}

Status Code: 404 Not Found

Example 2: Missing Required Field
{
    "name": "Aman"
}

Send this body in a POST request to /students.

Expected Response
{
    "message": "Valid name and course are required"
}

Status Code: 400 Bad Request

12. Testing an API Using curl

You can also test your Node.js API directly from the terminal.

curl Examples
GET Request
curl http://localhost:5000/students
POST Request
curl -X POST http://localhost:5000/students \
-H "Content-Type: application/json" \
-d '{"name":"Neha","course":"JavaScript"}'
DELETE Request
curl -X DELETE http://localhost:5000/students/1
Windows note: The multiline curl example above uses Unix-style line continuation. In Windows PowerShell, use curl.exe with the appropriate quoting rules, or enter the command on a single line.

13. Introduction to Automated API Testing

Manual testing is useful while developing an API, but automated testing helps check expected behavior repeatedly.

One popular Node.js testing tool is Supertest, which can send test requests to Express applications.

Install Supertest
npm install --save-dev supertest

For automated testing, it is useful to export the Express app separately from the code that starts the server.

app.js
const express = require("express");

const app = express();

app.get("/hello", (req, res) => {
    res.status(200).json({
        message: "Hello API"
    });
});

module.exports = app;
server.js
const app = require("./app");

app.listen(5000, () => {
    console.log("Server running on port 5000");
});
api.test.js
const request = require("supertest");
const assert = require("node:assert/strict");
const test = require("node:test");

const app = require("./app");

test("GET /hello returns the expected response", async () => {
    const response = await request(app).get("/hello");

    assert.equal(response.status, 200);

    assert.deepEqual(response.body, {
        message: "Hello API"
    });
});

Run the automated test using:

node --test api.test.js
Expected Result: The test passes if the API returns status code 200 and the expected JSON response.

14. API Testing Best Practices

  • Test both successful and unsuccessful requests.
  • Verify HTTP status codes.
  • Check response data types and JSON structure.
  • Test missing and invalid input values.
  • Test endpoints that require authentication.
  • Check that unauthorized users cannot access protected data.
  • Use automated tests for important functionality.
  • Avoid using real passwords or sensitive data in test examples.
  • Use a separate test database for database-backed applications.

15. Practical Assignment

Student Assignment – Test a Course Management API

Create a Node.js REST API to manage courses and test its endpoints using Postman.

  1. Create an Express server on port 5000.
  2. Create a GET route to display all courses.
  3. Create a GET route to display a course by ID.
  4. Create a POST route to add a new course.
  5. Create a PUT route to update an existing course.
  6. Create a DELETE route to remove a course.
  7. Test every route using Postman.
  8. Test invalid course IDs and missing required fields.
  9. Record the HTTP status codes for each request.
Example Course JSON
{
    "id": 1,
    "course_name": "Node.js",
    "duration": "3 Months",
    "fee": 5000
}

Bonus Task: Write an automated test that checks whether your GET endpoint returns status code 200.

16. Lesson Summary

In this lesson, you learned how to test REST APIs using Postman and curl, how to verify HTTP status codes, how to test CRUD operations, and how to write a basic automated API test using Supertest and Node.js.

Test Your Knowledge – API Testing

Select the correct answer for each question.

1. Which tool is commonly used to test REST APIs manually?
2. Which HTTP status code usually indicates successful resource creation?
3. Which HTTP method is commonly used to delete a resource?