DEV Community

cychu42
cychu42

Posted on

Starchart: Mocking A Database Part 1

The story

This week, I'm trying to write some tests for CRUD operation functions I made last week.
The project uses Vitest, so I had to go over documentation for that to see what I need to do. It similar enough to Jest that syntax feels familiar, but there are some differences like how to import certain functions.
Actually writing tests is familiar enough for me that it doesn't cause any issue, but I'm rather stumped about how to mock a database that's interfaced via Prisma, as this is really new to me. Thus, the progress has been slow for the task.

When I first started, I found Prisma documentation for writing test and mocking PrismaClient instance that API calls go through, but it's not appropripate for the project, as we use Vitest. Then, I found a blog post on Prisma official site that covers using Vitest, but I'm now stuck with an issue of the code not being able to find deeply nested properties that are common for API calls, such as prisma.user.create().

How Mocking Prisma Is Supposed To Works In Vitest

This explanation assumes you are familiar with the basics of witting test in Jest.

  1. You install an extension package via npm i -D vitest-mock-extended
  2. Make a __Mocks__ folder that has a file named after the module you want to mock. In this case, it would be a file that exports an instance of PrismaClient. Make sure to place this folder next to the real module.
  3. In the mocked module, place code to mock it:

     import { PrismaClient } from '@prisma/client'
     import { beforeEach } from 'vitest'
     import { mockDeep, mockReset } from 'vitest-mock-extended'
    
     beforeEach(() => {
     mockReset(prisma)
     })
    
     const prisma = mockDeep<PrismaClient>()
     export default prisma
    

    This imports all the tools needed, resets the mocked instance before each test, and exports an mocked instance to be used in a test. Because we are dealing with deeply nested properties like prisma.user.create(), you want to use mockDeep<>().

  4. In the test file you are writing, include import { expect, test, vi } from 'vitest' to import tools you need from Vitest, and use vi.mock(<route to the real module>) to tell Vitest you are mocking any mention of that route using the mocked modules in the Mocks folder next to the real one. You also need to import that mocked instance from the mocked module in step 3.

  5. Like using Jest, write test and import any function you want to test. Also, make sure to Vitest what the expected result of a function would be from the mocked module. For example, prisma.user.create.mockResolvedValue({ id: 1 }) tells it that you expect {id:1} object to be returned from the API call. See other functions here.

What now?

Either I try to figure out why it's not getting deeply nested properties as it's supposed to, or....I got a suggestion from the team that I can alternatively try to look into making a test database instead of mocking, so I need to look more into how to work with the dock-compose YAML file in the project to make it happen. So far, I managed to make a test database by editing the file, but something is preventing Prisma from connecting to it and throws Error: P1017: Server has closed the connection, which is an issue I need figure out in order to continue this approach.

Top comments (0)