Search code examples
typescriptrestexpressjestjsmikro-orm

How can I test my express rest api built with MikroORM?


index.ts:

import 'reflect-metadata'
import express from 'express'
import { EntityManager, EntityRepository, MikroORM, RequestContext } from '@mikro-orm/core'
import options from '../mikro-orm.config'
import { Music } from './entities/music.entity'
import router from './routes'

const app = express()

export const DI = {} as {
    orm: MikroORM,
    em: EntityManager,
    musicRepository: EntityRepository<Music>
}

async function bootstrap() {

    DI.orm = await MikroORM.init(options)

    DI.em = DI.orm.em
    DI.musicRepository = DI.orm.em.getRepository(Music)

    app.use(express.json())
    app.use(express.urlencoded({ extended: true }))
    app.use((req, res, next) => RequestContext.create(DI.orm.em, next))
    app.use(router)

    return { app, DI }

}

bootstrap()

export default bootstrap

music.test.ts

import request from 'supertest'
import bootstrap from '../index'

describe('musics', () => {

    it('should search the musics', async () => {

        const { DI, app } = await bootstrap()
    request(app)
        .get('/musics')
        .expect(200)
        .end()

    await DI.orm.close()

})

})

I mean, i would like to close the connection after all tests end, but i can not do this because the ORM connections is returned by the function bootstrap, that can only be called inside the "it" scope.

Can anyone help me to do something like this?

describe('musics', () => {

    afterAll(async () => {
        await DI.orm.close()
    })

    it('should search the musics', async () => {

        const { DI, app } = await bootstrap()

        request(app)
            .get('/musics')
            .expect(200)
            .end()

    })

})

the repository is: https://github.com/brenomacedo/g-track/tree/master/backend


Solution

  • Use beforeAll hook to create the connection, and store the result in the outer scope:

    describe('musics', () => {
    
        let context: any = {}; // TODO type this properly
    
        beforeAll(async () => {
            context = await bootstrap()
        })
    
        afterAll(async () => {
            await context.DI.orm.close()
        })
    
        it('should search the musics', async () => {
            request(context.app)
                .get('/musics')
                .expect(200)
                .end()
    
        })
    
    })