Testing NodeJS APIs pt. V: testing the REST API

Christian Benseler
3 min readDec 4, 2019

--

This is the fifth (and last) post from the series about testing NodeJS API with Jest and Supertest! Now we are ready to test a REST API with some authenticated endpoints!

Create the post.test.js inside test/controllers with the following code, that is the basic:

const request = require('supertest')let appdescribe('Post model Endpoints', () => {
let token
beforeAll(async () => {
app = require('../../app')
const res = await request(app)
.post('/users/signin')
.send({ email: 'fake@fake.com', password: 'fake' })
token = res.body.token
})
afterAll(async () => {
await app.close()
})
})

It is similar to the structure we wrote in the previous post, but now, beforethe tests, the script does a sign in and stores the token to be used in the endpoints that required authentication.

Now let’s test the GET /posts/:

it('should try to get post', async () => {let post = await Post.findOne({ title: 'test edit post title' })const res = await request(app)
.get('/posts/' + post._id)

expect(res.statusCode).toEqual(200)
expect(res.body).toHaveProperty('title')
expect(res.body.title).toEqual(post.title)
})

What is happening: the script queries the post (we inserted in the migration) and then requests the endpoint. It expects the status code to be 200 and that the response to contains a title property and that the value is the same from the post.

We can also test the GET /posts, the endpoint that lists all the posts:

it('should try to get all posts', async () => {
const res = await request(app)
.get('/posts/' )
expect(res.statusCode).toEqual(200)
expect(res.body).toHaveProperty('posts')
expect(res.body.posts).toHaveLength(2)
})

Now let’s test the PUT /posts/:id (the edit):

it('should try to edit post and success', async () => {let post = await Post.findOne({ title: 'test edit post title' })
const res = await request(app)
.put('/posts/' + post._id)
.set({ Authorization: 'Bearer ' + token })
.send({
title: 'new title'
})
expect(res.statusCode).toEqual(200)
expect(res.body.title).toEqual('new title')
})

Now the test tries to edit the post. Note that we send the Bearer token!

But, what happens if we try to edit the post without the Bearer token (in other words, with no authentication)? It should return an error:

it('should try to edit post without bearer token and fail', async () => {
const res = await request(app)
.put('/posts/' + post._id)
.send({
title: 'new title'
})
expect(res.statusCode).toEqual(401)})

Now let’s test the /POST /posts (the endpoint that creates a new post entity):

it('should try to create post and success', async () => {
const res = await request(app)
.post('/posts')
.set({ Authorization: 'Bearer ' + token })
.send({
title: 'new title'
})
expect(res.statusCode).toEqual(200)})it('should try to create post without params and fail', async () => {const res = await request(app)
.post('/posts')
.set({ Authorization: 'Bearer ' + token })
.send()
expect(res.statusCode).not.toEqual(200)})

And last, the DELETE /posts/:id

it('should try to delete post and success', async () => {
const postDelete = await Post.findOne({ title: 'test delete post title' })
const res = await request(app)
.delete('/posts/' + postDelete._id)
.set({ Authorization: 'Bearer ' + token })
expect(res.statusCode).toEqual(200)})

With this, we have tested all the endpoints from the REST API we have created for the Post model! Of course you can create a bunch of other tests, but this is in my opinion the basics and a good start point!

Link for the 5 parts from this tutorial:

The source code from the full project is in the Github and this tag has the exact version from this example.

--

--