All my colleagues know that I love testing. I really think that tests are a neat tool that can leverage our productivity and the quality of what we write. That being said, in this series of articles, we will be seeing how we can test everyday stuff like API endpoints, integration with databases, and third-party services. In this first part, we are going to see how to test express endpoints, come with me.
As an example, we are going to start with this basic hello world application:
index.js:
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
package.json:
{
"name": "testing",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"express": "^4.17.2"
},
"scripts": {
"start": "node index.js"
}
}
For the test framework, we are going to use Jest. So, let’s install it using the command:
npm install jest ---save-dev
And now, we can write our first test:
test/app.test.js:
it('should say hello world', () => {
console.log('Hello World!')
})
And now we can finally run our first test using the command:
npx jest
You should see something similar on the terminal if everything ran smoothly:
➜ npx jest
console.log
Hello World!
at Object.<anonymous> (test/app.test.js:2:11)
PASS ./test/app.test.js
✓ should say hello world (18 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.302 s, estimated 1 s
Ran all test suites.
To send requests to our express application, we are going to use supertest. Supertest provides us with lots of functions to make our life easier. Let’s go ahead and install it using:
npm install supertest --save-dev
In order to test our application, we need to move some of the express app creation logic into a file we can import from the test file:
index.js:
const createApp = require('./src/createApp')
const app = createApp()
const port = 3000
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
src/createApp.js:
const express = require('express')
module.exports = () => {
const app = express()
app.get('/', (req, res) => {
res.send('Hello World!')
})
return app
}
Now that we have all set, we can test our Hello World endpoint:
test/app.test.js:
const request = require('supertest')
const createApp = require('../src/createApp')
it('should say hello world', async () => {
await request(createApp())
.get('/')
.expect(200, 'Hello World!')
})
If everything went well, you should see something like this on the terminal:
➜ testing npx jest
PASS ./test/app.test.js
✓ should say hello world (31 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.726 s, estimated 1 s
Ran all test suites.
That’s it! We successfully ran our first express test. Before we finish this first part, lets break down what is happening:
await request(createApp())
Here, we create an instance of our app and pass it to supertest. Supertest does all the heavy work of binding our application to a specific port and making sure each request goes to the right place.
.get('/')
Here, we tell supertest to send a GET request to the / path.
.expect(200, 'Hello World!')
And finally, here we make sure that the response status is 200 and
the body is exactly Hello World!.
Supertest is a very helpful library, it allows us to verify different behaviors of our application like:
The endpoint should return a 500 error:
.expect(500)
The endpoint should return a object:
.expect(200, {
lorem: 'ipsum'
})
And many others. You can know more about supertest here.
Continue reading: Node.js testing - Database