How To Mock Prisma With NestJS

Author: Ethan Glover
Last Updated: Jun 23, 2022, 12:06 AM UTC
Prisma

When working with NestJS it can sometimes be difficult to figure out how to write tests around the dependency injection system. In searching for how I could write unit tests for services when using Prisma I found a lot of wild and hacky workarounds. But by consulting Prisma documentation I found a very simple, and clean answer.

First thing, let's say we have this code that creates a new user. You'll notice we're using dependency injection to bring in a PrismaService which connects to the database.

constructor(private readonly prisma: PrismaService) {}

async create(
  data: CreateOneUserArgs,
  select?: Prisma.UserSelect
): Promise<Partial<User>> {
  return this.prisma.user.create({
    ...data,
    select,
  });
}

First we need to follow the Prisma documentation to create mock objects. Most importantly for our case is creating the singleton.ts file.

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

import prisma from './client';

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

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

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

We can then use the exported prismaMock as a provider in our unit test.

let service: UserService;

beforeEach(async () => {
  const module: TestingModule = await Test.createTestingModule({
    providers: [
      UserService,
      { provide: PrismaService, useValue: prismaMock },
    ],
  }).compile();

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

Then just return to the Prisma documentation to keep following their example to write a test for creating a new user with the singleton method.

test('should create new user ', async () => {
  const user = {
    id: 1,
    name: 'Jill',
    email: 'hello@example.com',
    acceptTermsAndConditions: true,
  }

  prismaMock.user.create.mockResolvedValue(user)

  await expect(service.create(user)).resolves.toEqual({
    id: 1,
    name: 'Jill',
    email: 'hello@example.com',
  })
})