How to test API routes in NextJS

6 June 2020

I'm currently working on a NextJS project where we're using api folder for all sort of calls: fetching data, authorization... Well, basically that's it for now, we're just starting. :)

So I had some questions on how to approach it, and thanks to Mason's post and a few stack overflow issues, I was able to construct something that wokred for our case.

In that case, I needed to test

  1. API function accepts and sends back the same headers (e.g. session key)
  2. API responds with a certain status (e.g. 200)
  3. API responds with a pre-defined object structure (e.g. it had to be data: {})

For that I've used

This is how it all came together in our .test.ts file

import nock from 'nock' import nodeMocks from 'node-mocks-http' import auth from '../auth' describe('API function', () => { // We create req and res mocks const req = nodeMocks.createRequest() const res = nodeMocks.createResponse() // We're using the same headers and we're mocking .status and .end function, // because we're going to see how many times they've called // and what they've called with beforeEach(() => { req.headers = { username: 'test', password: 'test123' } res.status = jest.fn(function () { return this }) res.end = jest.fn() }) // We need to reset mocks after every test so that we could reuse them in another afterEach(() => { jest.resetAllMocks() nock.restore() }) it('sends data with session key on successful call', async () => { // This is what server sends to us as a response to our requests. // So we create a similar object here for mocking purposes. const successReply = { result: 1, session: 'testsessionId', text: 'Auth ok', } // We instruct nock to send that object/reply and status 200 when our // API route is called nock(process.env.BASE_API_URL) .post(/authenticate$/) .reply(200, successReply) // Using async/await here to wait for the response await auth(req, res) // And here we're checking our mocks that we created in beforeEach function expect(res.status).toHaveBeenCalledTimes(1) expect(res.status).toHaveBeenCalledWith(200) expect(res.end).toHaveBeenCalledTimes(1) expect(res.end).toHaveBeenCalledWith( JSON.stringify({ data: { session: successReply.session } }), ) }) })

That is basically it. 🎉

©2024 Rail Yard Works LTD is registered in England and Wales, no. 12126621.