How to Test with Prisma

Typescript has undoubtedly been one of the greatest type system ever to be created. In fact it is so flexible, an entire ORM can be built around it while having all columns in the uderl

File Structure

My current setup looks like this:

prisma
  index.ts
src
  routes
    index.ts
  etc...
node_modules

If you use a different structure, please be sure to put the files in the correct place.

Setting Up

First, be sure to install ts-jest using the following guide: https://github.com/kulshekhar/ts-jest#getting-started

Then create a folder called __mocks__ in your root folder (where node_modules lives). Inside that create a folder called @prisma and inside that, create a client.ts file with the following:

import { mockDeep } from 'jest-mock-extended';
import { PrismaClient as OriginaPrismaClient } from '@prisma/client';

const mockPrisma = mockDeep<OriginaPrismaClient>();

export const PrismaClient = () => mockPrisma;

This will mock the entire Prisma client and allow you to override the return values.

Then create a global.ts file under src/utils/test which looks like so:

// eslint-disable-next-line import/no-extraneous-dependencies
import { mocked } from 'ts-jest/utils';
import { prisma } from '../../../prisma';

const mockedPrisma = mocked(prisma, true);

declare global {
  const $prisma: typeof mockedPrisma;
  namespace NodeJS {
    interface Global {
      $prisma: typeof mockedPrisma;
    }
  }
}

global.$prisma = mockedPrisma;

This will add a variable $prisma to the global variables allowing you to easily override any of the queries.

Finally, we need to tell jest to load the above file so the $prisma variable can be accessed. Add this to your jest config.

module.exports = {
  ...
  setupFilesAfterEnv: ['./src/utils/test/global.ts'],
}

That's it! It should be working now.

Usage

Inside any test, you can mock the prisma instance.

it('returns image from database', async () => {
  $prisma.posts.count.mockResolvedValue(1);
  $prisma.posts.findMany.mockResolvedValue([
    {
      id: 'id',
      title: 'hello world',
      description: 'this is a blog post',
    },
  ]);

  const response = await request(); // replace this with your actual test
  expect(response.status).toStrictEqual(200);
  expect(response.body.data.posts).toMatchSnapshot(); // or .toBe([{ id: ..., title: ..., description: ...}]);
});

P.S. I've set up a real-world example here based on the Prisma starter example.