Samuel A. Souza
Samuel A. Souza

Reputation: 377

How to use Jest and Supertest with Fastify?

I'm trying to use Jest and Supertest with Fastify. I have this test file.

// @ts-nocheck
import { FastifyInstance } from 'fastify'
import request from 'supertest'
import app from '../app'

let server: FastifyInstance

beforeAll(async () => {
    server = app.server;
})

afterAll(() => {
    server.close()
})

test('Should get a 200 OK', async () => {
    const response = await request(server).get('/')
    expect(response.status).toBe(200)
})

My app.ts:

import fastify from 'fastify'
import dotenv from 'dotenv'

dotenv.config()

import appRoute from './routes/app'

const app = fastify({ logger: true })

app.register(appRoute)

export default app

But I always get a timeout... Could anyone provide an example of how to use Jest and Supertest with Fastify?

Upvotes: 3

Views: 5526

Answers (2)

Sherif eldeeb
Sherif eldeeb

Reputation: 2206

before I answer your question, I would recommend using the built-in feature fastify.inject() which uses light-my-request for some reasons

  • it doesn't create a test server, whereas superTest silently creates a test server
  • it waits until all plugins are registered and the server is ready for test
  • no need to install an additional package "superTest"

I will explain how to perform the test in either case

using .inject():

let app = Fastify({...});
app.inject({method: 'GET', URL: '/'})
  .then(res=>{/
   //Make the actual test here, using Jest or any library of your choice
   expect(res.statusCode).toBe(200)
   // ...other expectations
  })

or you can build your fake request like this:

app.inject()
 .get('/')
 .headers({...})
 .then(res=>{ /* your test here */}

using SuperTest

this method is a bit similar to the previous one, with some additional work

let app = Fastify({...})

//We need to wait until the app is ready for the test
await app.ready();

//Now we can use superTest to start our test server
superTest(app.server)
 .get('/')
 .expect(200)
 // ...other expectations

Upvotes: 3

Lin Du
Lin Du

Reputation: 102457

There is an example in the official document at the bottom about writing testings with supertest. See testing

Make sure you call the done callback of the fasity.register() API.

index.js:

const Fastify = require('fastify');

const app = Fastify({ logger: true });

app.register((instance, opts, done) => {
  instance.get('/', (request, reply) => {
    reply.send({ hello: 'world' });
  });
  done();
});

module.exports = app;

index.test.js:

const supertest = require('supertest');
const app = require('./');

afterAll(() => app.close());

test('GET `/` route', async () => {
  await app.ready();

  const response = await supertest(app.server)
    .get('/')
    .expect(200)
    .expect('Content-Type', 'application/json; charset=utf-8');

  expect(response.body).toEqual({ hello: 'world' });
});

Test result:

❯ npm run test
$ jest
{"level":30,"time":1673234788774,"pid":70,"hostname":"noderfv2fs-ky0o","reqId":"req-1","req":{"method":"GET","url":"/","hostname":"127.0.0.1:62766"},"msg":"incoming request"}
{"level":30,"time":1673234788777,"pid":70,"hostname":"noderfv2fs-ky0o","reqId":"req-1","res":{"statusCode":200},"responseTime":2.5850000000000364,"msg":"request completed"}
 PASS  ./index.test.js
  ✓ GET `/` route (489 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.269 s, estimated 3 s
Ran all test suites.

stackblitz(Open using Chrome, there is a bug when run npm run test using Microsoft Edge)

Upvotes: 4

Related Questions