Home > Enterprise >  How to unit test this prisma.service
How to unit test this prisma.service

Time:11-13

I'm having trouble unit testing a prisma.service.ts file:

import { INestApplication, Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient {
  async enableShutdownHooks(app: INestApplication) {
    this.$on('beforeExit', async () => {
      await app.close();
    });
  }
}

The prisma.service.spec.ts I have currently looks like this:

import { INestApplication } from '@nestjs/common';
import { NestFastifyApplication } from '@nestjs/platform-fastify';
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaService } from './prisma.service';

const MockApp = jest.fn<Partial<INestApplication>, []>(() => ({
  close: jest.fn(),
}));

describe('PrismaService', () => {
  let service: PrismaService;
  let app: NestFastifyApplication;

  beforeEach(async () => {
    app = MockApp() as NestFastifyApplication;
    const module: TestingModule = await Test.createTestingModule({
      providers: [PrismaService],
    }).compile();

    service = module.get<PrismaService>(PrismaService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('enableShutdownHooks', () => {
    it('should call $on and successfully close the app', async () => {

      const spy = jest.spyOn(PrismaService.prototype, '$on')
      .mockImplementation(async () => {
        await app.close();
      });

      await service.enableShutdownHooks(app);

      expect(spy).toBeCalledTimes(1);
      expect(app.close).toBeCalledTimes(1);
      spy.mockRestore();
    });
  });
});

However, this does not test line 8 of prisma.service.ts:

await app.close();

because I am mocking the implementation of this.$on('beforeExit', callback), with a copy of its original implementation. Even if I don't mock it, app.close() never gets called.

Is there a way to test this line?

CodePudding user response:

Could you try using a callback:

jest
  .spyOn(service, '$on')
  .mockImplementation(async (eventType, cb) => cb(() => Promise.resolve()))

await service.enableShutdownHooks(app);

expect(service.$on).toBeCalledTimes(1);

That allows you to use the callback to invoke the function where await app.close() is located.

  • Related