How to Test Your Custom Server in Next.js

by Nicklas Envall

This article will show you how you can set up tests for your custom server routes in your next.js application with ease. All the examples contain demonstrations with an express server.

We will use Mocha and Supertest when testing our routes. This article will show you two different approaches which are both depended on if you have a serverless custom server or not. The two approaches we will cover are:

  1. How you can test your custom serverless routes in your Next.js app.
  2. How you can test your custom server routes in your Next.js app.

1. How to Test Your Serverless Routes in Next.js

We will start by setting up a very basic serverless next.js app and use it as an example application. You can read more at next.js blog post regarding serverless deployment.

npx create-next-app test-example
cd test-example
npm install --save express

Now delete everything in next.config.js and paste the following:

module.exports = {
 target: 'serverless'
}

Add the following code to /pages/index.js

const Home = () => (
 <div>
     <h1>home page</h1>
 </div>
)

export default Home

Add the following code to /pages/about.js

const About = () => (
 <div>
     <h1>about page</h1>
 </div>
)

export default About

Create a server.js and paste the following code below into the file. Before continuing, you should also comment out module.exports = server and uncomment server.listen and try out the server to ensure that the routes work. Remember to npm run build if you decide to start the server and try out the routes.

const express = require('express')

const server = express()

const home = require('./.next/serverless/pages/index.js')
const about = require('./.next/serverless/pages/about.js')

server.get('/', (req, res) => home.render(req, res))
server.get('/about', (req, res) => about.render(req, res))

// server.listen(3000, () => console.log('Listening on http://localhost:3000'))

module.exports = server

Step: 1 Setup the testing environment

As mentioned in the introduction we will use Mocha and Supertest while testing our routes. So, install them with the following commands:

npm install mocha --save-dev
npm install supertest --save-dev

Now add "mocha": "mocha" to your package.json:

  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start",
    "mocha": "mocha"
  },

Now create a folder called /test and then add a file named test.js to the folder. The route to the javascript file should be /test/test.js.

Step: 2 Create the tests

Now we can finally start adding tests in our test.js. In this example, we use Supertest, which allows us to test the routes of our server. Note that in the example, we import the server we created in the beginning and use it at line 5 supertest.agent(server).

const supertest = require('supertest');
const mocha = require('mocha');
const server = require('../server.js');

const agent = supertest.agent(server);

describe('This will test status codes 200 and 404', () => {

   it('should return 200', function(done) {
       agent.get('/').expect(200, done);
   });

   it('should return 200', function(done) {
       agent.get('/about').expect(200, done);
    });

   it('should return 404', function(done) {
       agent.get('/no').expect(404, done);
   });

});

Step 3: Run the tests

npm run build
npm run mocha

The result:

Mocha Nextjs result in Windows console

2. How to Test Your Custom Server Routes in Next.js

With this approach, you will only be able to test your specific custom server routes. We will use Mocha and Supertest testing our routes. So, install them by pasting the following commands into your terminal:

npm install mocha --save-dev
npm install supertest --save-dev

Step 1: Put your routes in a specific folder

The first step is to put the routes you want to test into a specific folder. Create a folder called /routes and then create a file called users.js and put it inside the /routes folder. The path should be /routes/users.js. Now in users.js, we will create our routes:

var express = require('express');
var router = express.Router();

router.get('/all', (req, res) => {
   const data = [
       {name: 'mark'},
       {name: 'steve'},
       {name: 'jessica'}
   ]
   res.json(data);
});

router.get('/yes', (req, res) => {
   res.status(200).send('Success!');
});

router.get('/no', (req, res) => {
   res.status(404).send('Not Found!');
});

module.exports = router;

Now inside our server (usually named server.js), we will add the routes in the following manner:

var usersRoutes = require('./routes/users');
app.prepare()
.then(() => {

 const server = express();
 server.use('/users', testRoutes);

 // etc..
}

On route /users/all we will receive all the users in a JSON response. While users/yes will return a status code 200 and the string “Success!”. Lastly, the route users/no will return a status code 404 and the string “Not Found!”.

Now, just to be sure if everything worked according to plan, start the server and open your browser and request the routes. Beware that you might get a 304 code if it's cached when requesting users/yes.

localhost:3000/users/all
localhost:3000/users/yes
localhost:3000/users/no

Step 2: Create tests for your routes

We probably do not want to use the browser each time we want to check something. So now we'll set up the actual tests.

Firstly add the following to your package.json:

"mocha": "mocha"

Now create a folder called /test and then add a file named test.js to it. In test.js we can now add our tests. The important thing to note here is that we import the routes, not the server itself.

const assert = require('assert');
const supertest = require('supertest');
const mocha = require('mocha');
const express = require('express');

// routes we are testing
const routes = require("../routes/users.js");

// setup app
const app = express();
app.use('/users', routes);
const agent = supertest.agent(app);

describe('This will test yes and no route', () => {

   it('should return the users in an array', function(done) {
       agent.get("/users/all")
       .set('Accept', 'application/json')
       .expect(function(res) {
           assert.equal(res.body[0].name, 'mark');
           assert.equal(res.body[1].name, 'steve');
           assert.equal(res.body[2].name, 'jessica');
           assert.notEqual(res.body[1].name, 'mark');
       })
       .expect(200, done);
   });

   it('should return 200', function(done) {
       agent.get('/users/yes')
           .expect(200, done);
   });

   it('should return 404', function(done) {
       agent.get('/users/no')
           .expect(404, done);
   });
});

Step 3: Run the tests

Now the final part is to run the tests:

npm run mocha

The result:

Mocha Nextjs result only