Unit testing Next.js API routes

Unit testing Next.js API routes is possible with jest and straightforward once you see an example.

Straight from the Next.js docs, API route handlers look like this:

// pages/api/user.js
export default (req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify({ name: 'John Doe' }));
};

Hey, that's just a function! Those are easy to test!

I hear you, internet friend. It is a function indeed and functions are easy to test, but this has a bit more going on than just adding 2 numbers.

Example API route#

This blog is built with Next.js so I added this /api/animal/[animal] route, which accepts a dynamic [animal] parameter at the end and returns a JSON object with a dynamic message.

// /pages/api/[animal].js
export default function handleAnimal(req, res) {
  const {
    query: { animal },
  } = req;

  res.statusCode = 200;
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify({ message: `Your favorite animal is ${animal}` }));
}

The unit test#

The key here is the createMocks utility provided by node-mocks-http. It creates mock req and res objects that you can later interrogate after your async route handler executes.

// __tests__/animal.test.js
// 馃毃 Remember to keep your `*.test.js` files out of your `/pages` directory!
import { createMocks } from 'node-mocks-http';
import handleAnimal from '../pages/api/animal/[animal]';

describe('/api/[animal]', () => {
  test('returns a message with the specified animal', async () => {
    const { req, res } = createMocks({
      method: 'GET',
      query: {
        animal: 'dog',
      },
    });

    await handleAnimal(req, res);

    expect(res._getStatusCode()).toBe(200);
    expect(JSON.parse(res._getData())).toEqual(
      expect.objectContaining({
        message: 'Your favorite animal is dog',
      }),
    );
  });
});

That's it! Know of a better way? Find me on Twitter and share!

Join the Newsletter

I write about software development of all kinds (mostly front-end).

I won't send you spam. Unsubscribe at any time.