Mock Prisma Schema in Bun Tests


Writing unit tests for your code is usually straightforward when using popular test frameworks like Jest or Vitest. You can easily mock dependencies and focus your specs on specific units of logic. However, when working with Bun — especially if you’re trying to mock Prisma database interactions — things can be a bit different.
In this post, we’ll explore two approaches for mocking Prisma in Bun
1.Spying on Methods with spyOn
If you want to track method calls (like Prisma Client methods), you can use Bun’s built-in spyOn
method from bun:test
. This is ideal when you just want to observe behavior and assert how methods were called.
Example
import { test, expect, spyOn } from "bun:test";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
test("should find user by id", async () => {
const spy = spyOn(prisma.user, "findUnique");
await prisma.user.findUnique({ where: { id: 1 } });
expect(spy).toHaveBeenCalledTimes(1);
expect(spy.mock.calls[0][0]).toEqual({ where: { id: 1 } });
});
2.Mock the Entire Module
Consider this example: we have a function that fetches a user from the database based on an ID.
import { getDbClient } from '~/lib/getDbClient';
export async function findUser(id: number) {
const db = getDbClient();
const user = await db.user.findUnique({ where: { entity_id: id } });
if (!user) return { status: 'redirect', redirectUrl: href('/login')};
return { status: 'valid', user };
}
Here, getDbClient()
returns the Prisma instance, and we use its findUnique()
method to locate a user.
The Challenge
If we try to test this directly, it will attempt to call the actual database. That’s undesirable for a unit test, so we need a way to mock the Prisma client.
The Solution: mockModule
We can accomplish this using Bun’s mock.module()
method. Here’s how:
Creating a Mock User
First, we create a helper method:
function createMockUser(overrides: Partial<UserEntity> = {}): UserEntity {
const defaultUser = {
email: 'john@example.com',
created_at: new Date(),
updated_at: new Date(),
is_active: 1,
firstname: 'John',
lastname: 'Doe',
dob: null,
gender: null,
password_hash: null,
};
return {
...defaultUser,
...overrides,
};
}
Writing the Spec
Then, we use mockModule()
in our test:
Then we will write the spec for the function by mocking the dbClient like below
import { afterEach, beforeEach, describe, expect, it, mock } from 'bun:test';
import { mockModule } from '~/lib/mockModule';
describe('findUser', () => {
beforeEach(() => {
mock.module('~/lib/getDbClient', () => ({}));
});
afterEach(() => {
mock.restore();
});
it('should redirect if user not found', async () => {
using mocked = await mockModule('~/lib/getDbClient', () => ({
getDbClient: () => ({
user_entity: {
findUnique: () => null,
},
}),
}));
const result = await findUser(1);
assertRedirect(result, '/login?msg=link_expired&link_error=2');
});
it('should return valid user', async () => {
const mockUser = createMockUser();
using mocked = await mockModule('~/lib/getDbClient', () => ({
getDbClient: () => ({
user_entity: {
findUnique: () => mockUser,
},
}),
}));
const result = await findUser(1);
expect(result.status).toBe('valid');
if (result.status === 'valid') {
expect(result.user).toEqual(mockUser);
}
});
});
The mockModule
Utility
Here’s the helper used to swap in and restore mock implementations:
import { mock } from 'bun:test';
/**
* Mocks a module by merging its actual exports with custom implementations.
*/
export const mockModule = async (
modulePath: string,
renderMocks: () => Record<string, any>
) => {
const original = { ...(await import(modulePath)) };
const mocks = renderMocks();
const result = {
...original,
...mocks,
};
mock.module(modulePath, () => result);
return {
[Symbol.dispose]: () => {
mock.module(modulePath, () => original);
},
};
};
With this approach, you can effectively mock Prisma instances in Bun, making your specs focused and independent of actual database connections — all without relying on Jest or Vitest.
If you’re migrating to Bun or starting fresh, this method gives you a clean, reliable way to test database-related logic in isolation.
Subscribe to my newsletter
Read articles from nidhinkumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
