Testing HTTP Endpoints Using Jest and Supertest
Updated: May 3, 2023
![](https://static.wixstatic.com/media/11062b_603d1d312aba41d59f7dcd501395c475~mv2.jpg/v1/fill/w_980,h_654,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/11062b_603d1d312aba41d59f7dcd501395c475~mv2.jpg)
How Jest and Supertest are used together in test cases written in Node.js REST API?
est and Supertest are two popular tools used together in Node.js REST API test cases to enable automated testing of HTTP requests and responses.
Jest is a testing framework for JavaScript code, while Supertest is a module for testing HTTP requests in Node.js applications. Jest provides a framework for writing and running tests, and Supertest provides an easy-to-use API for testing HTTP endpoints.
Here are the steps to use Jest and Supertest together in test cases written for a Node.js REST API:
1. Install Jest and Supertest in your Node.js project using npm or yarn:
npm install --save-dev jest supertest
2. Create a test file for your API endpoints in the __tests__ directory of your project. For example, __tests__/api.test.js.
3. Import the necessary dependencies in your test file:
const app = require('../app'); // your Node.js app
const request = require('supertest');
4. Write test cases using Jest's describe and test functions, and Supertest's request function. Here is an example:
describe('API endpoints', () => {
test('GET /api/users should return 200 OK', async () => {
const response = await request(app).get('/api/users');
expect(response.status).toBe(200);
});
test('POST /api/users should create a new user', async () => {
const newUser = { name: 'John Doe', email: 'johndoe@example.com' };
const response = await request(app).post('/api/users').send(newUser);
expect(response.status).toBe(201);
expect(response.body.name).toBe(newUser.name);
expect(response.body.email).toBe(newUser.email);
});
});
In this example, the first test case checks if the GET /api/users endpoint returns a 200 status code, and the second test case checks if the POST /api/users endpoint creates a new user with the correct name and email.
5. Run your tests using Jest's CLI:
npx jest
Note: Jest will automatically detect and run all the test files in your __tests__ directory.
That's it! Jest and Supertest make it easy to write automated tests for your Node.js REST API and ensure that your endpoints are working correctly.
Testing HTTP Endpoints
Following Test cases are written using the Jest, Supertest testing framework to test an HTTP endpoints that creates a user in a web application. Install Libraries:
> npm install -D jest supertest
Example
describe("POST /users", () => { describe("Given username & password", ()=> { test("Should send response with 200 status code", async()=> { const response = await request(app).post("/users").send({ username:"username", password: "password" }) expect(response.statusCode).toBe(200) })
})
})
The describe() function is used to group related tests together and provide a description of what the tests are testing. In this case, there are two nested describe() functions. The outer one describes the endpoint being tested (POST /users), while the inner one describes the scenario being tested (Given username & password).
The test() function is used to define a single test case, which in this case checks whether the endpoint responds with a 200 status code when valid username and password data are sent in the request body. The async keyword is used to indicate that this test case uses asynchronous code.
Inside the test case, the request() function is used to send an HTTP POST request to the "/users" endpoint of the app (presumably a Express.js application) with the username and password values in the request body. The await keyword is used to wait for the response from the server before continuing.
Finally, the expect() function is used to assert that the response object has a statusCode property with the value of 200, indicating that the request was successful. If the assertion fails, the test case will fail.
Example
test("Should specify JSON in the content type header", async()=> {
const response = await request(app).post("/users").send({
username:"username",
password: "password"
})
expect(response.headers['content-type']).toEqual(expect.stringContaining("json"))
})
This code is a test case that checks whether the response from a POST request to the /users endpoint of a web application has the correct content type header.
The test() function is used to define a single test case, which in this case checks whether the response from the server has a content type header that specifies JSON. The async keyword is used to indicate that this test case uses asynchronous code.
Inside the test case, the request() function is used to send an HTTP POST request to the /users endpoint of the app (presumably an Express.js application) with the username and password values in the request body. The await keyword is used to wait for the response from the server before continuing.
The expect() function is used to assert that the response object has a headers property that contains a content-type header that includes the string "json". The toEqual() function is a Jest matcher that checks that the actual value of the content-type header contains the expected value ("json"). The expect.stringContaining() function is used to create a matcher that matches any string that contains the substring "json".
If the assertion fails, the test case will fail. This ensures that the response from the server includes the correct content type header, which is important for clients that need to correctly parse the response data.
What is expect function?
In the above code snippet, expect is a function provided by the Jest testing framework that is used to define an assertion in a test case.
Assertions are statements that verify whether certain conditions are true or false. In Jest, assertions are created using the expect function.
The expect function takes a single argument, which is the value that you want to make an assertion about. This argument is usually the result of a function call that you are testing.
After calling expect, you chain one or more matcher functions to it, which define the conditions that must be true in order for the test to pass. Matchers compare the value passed to expect with an expected value or condition.
If the assertion defined by the expect and its chained matchers are true, the test case passes. If the assertion is false, the test case fails.
In the code snippet you provided, expect is used to make an assertion about the content type header of an HTTP response. Specifically, it checks whether the header includes the string "json". If the header includes "json", the test case passes. If not, the test case fails.
Example test("Reponse has user id", async()=> { const response = await request(app).post("/users").send({ username:"username", password: "password" }) expect(response.body.userId).toBeDefined() }) In this above code is a test case that checks whether the response from a POST request to the /users endpoint of a web application contains a userId property in its response body.
The test() function is used to define a single test case, which in this case checks whether the response from the server has a userId property in its response body. The async keyword is used to indicate that this test case uses asynchronous code.
Inside the test case, the request() function is used to send an HTTP POST request to the /users endpoint of the app (presumably an Express.js application) with the username and password values in the request body. The await keyword is used to wait for the response from the server before continuing.
The expect() function is used to assert that the response object has a body property that includes a userId property. The toBeDefined() matcher checks whether the userId property exists and is not undefined.
If the assertion defined by the expect() function is true (i.e. the userId property exists and is not undefined), the test case passes. If the assertion is false, the test case fails.
This test case ensures that the server creates a new user and returns the userId in the response body. It is a good way to test that the server is functioning correctly, and that clients can retrieve the userId after creating a new user.
Example
test("Should respond with status code of 400", async()=> {
const bodyData = [
{username: "username"},
{password: "password"}
]
for (const body of bodyData) {
const response = await request(app).post("/users").send(body)
expect(response.statusCode).toBe(400)
}
})
In the above test case is using a testing framework (such as Jest) to test a web application's endpoint that creates new users.
The test case is checking if the endpoint is responding with a status code of 400 when a request is made with invalid data.
The test is using an asynchronous function and the await keyword to make a POST request to the endpoint (/users) with a body that contains invalid data (in this case, missing a required field).
The expect function is then used to verify that the response status code is 400 (Bad Request) for each of the invalid requests made.
Overall, this test case is ensuring that the application's endpoint handles invalid data as expected and returns an appropriate error response.
Comments