How do I unit test an API mocking PrismaClient when the API is written in CommonJS?

Viewed 171

I am testing a nodejs express API with a PG db wrapped with Prisma ORM
I configured a testing singleton instance as described by Prisma docs
Since the API is implemented in CommonJS and not TS, I had to make some changes as described in this beautiful page.
Here is a synthesis of what I did, will try to make it short, so it's easier to read

orgs.js (A GET route served by the mock server later on ...)

const Router = require('express-promise-router')
const router = new Router()
const PrismaPool = require('../db/PrismaPool');

module.exports = router

 router.get('/assessments', async (req, res) => {
    try{
        const prisma =  PrismaPool.getInstance();
        const data = await prisma.org.findUnique({
            select:{
                assessments:true,
            },
            where: {
              id: res.locals.orgId,
            },
        })
        res.send(data)

    }
    catch(err){
        handleError(err, "[GET]/orgs/assessments", 400, req, res) 
    }
})

PrismaPool.js (A wrapper to access the unique prisma client instance)


const prisma = require('./PrismaClientInstance').default

class PrismaPool {
    constructor() {
        throw new Error('Use PrismaPool.getInstance()');
    }
    static getInstance() {
        return prisma
    }
}
module.exports = PrismaPool;

PrismaClientInstance.js The unique instance of PrismaClient class. This is the tricky part stitching between the CommonJS world and the TS world.

'use strict';
exports.__esModule = true;
const { PrismaClient } = require('@prisma/client')

const prisma = new PrismaClient()

exports['default'] = prisma;

All this configuration works GREAT at runtime, now, when wrapping it with JEST in unit tests, things go south quickly ...

mock_server.js (a simplified server to expose the orgs API above)

const http = require('http');
const express = require('express');

var orgsRouter = require('../orgs');
const app = express();
app.use('/orgs', orgsRouter);

const port = 3011
app.set('port', port);

const server = http.createServer(app);

function onError(error) {
    // herror handling
}


function onListening() {
    // some debug messages
}

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

module.exports = server

PrismaSingletonForTesting.ts (A jest deep mock of the PrismaClient instance)

import { PrismaClient } from '@prisma/client'
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended'

import prisma from './PrismaClientInstance'

jest.mock('./PrismaClientInstance', () => ({
  __esModule: true,
  default: mockDeep<PrismaClient>()
}))

beforeEach(() => {
  mockReset(prismaMock)
})

export const prismaMock = prisma as unknown as DeepMockProxy<PrismaClient>

orgs.test.js (The tests of the orgs API)

const Request = require("request")
const { prismaMock } = require('../../db/PrismaSingletonForTesting')
const TEST_ORGID = 1

describe('egrest server', () => {
    let server
    beforeAll(() => {
        server = require('./test_server')
    })
    afterAll(() => {
        server.close()
    })

    describe('assessments', () => {
        let data = {}
        beforeAll(() => {
            const testorg = {
                id: TEST_ORGID,
                name: 'jestest',
                admin:33,
                avail_tests: 1234
            }
            prismaMock.org.findUnique.mockResolvedValue(testorg)
        })
        it(`read remaining assessments for org ${TEST_ORGID}`, (done) => {
            Request.get("http://localhost:3011/orgs/assessments", (error, response, body) => {
                data.status = response.statusCode
                data.body = body
                data.error = error
                console.dir(body)
                done()
            })
        })
    })
})

I also configured .jest.config with the required line setupFilesAfterEnv: ['./db/PrismaSingletonForTesting.ts']

When I run this test, I get data=undefined in orgs.js, even-though I mocked prisma.org.findUnique by doing prismaMock.org.findUnique.mockResolvedValue(testorg) as described by prisma docs.
Any help would be appreciated.

0 Answers
Related