Excerpt: Learn how to mock a module Jest-style while testing your NodeJS projects using Bun’s built-in testing framework. This tutorial will guide you through setting up and testing a CustomerService with Prisma ORM, demonstrating how to mock the Prisma client for efficient testing without real database interactions.
1. Introduction
In this tutorial, we’ll explore how to test a NodeJS project using Bun’s built-in testing framework instead of the traditional Jest approach. We’ll focus on a CustomerService that manages customer data, using Prisma as an ORM. The key aspect we’ll cover is how to mock the Prisma client to avoid real database interactions during testing.
2. Project Setup
First, clone the project repository:
git clone https://github.com/NickyBall/bun-service-prisma-mock-tutorial
cd bun-service-prisma-mock-tutorial
Install dependencies:
bun install
3. Project Structure
Our project consists of:
CustomerService
: Manages customer dataCustomer
model: Containsid
andname
fields- Prisma ORM for database interactions
Let’s take a look at the key files:
3.1 schema.prisma
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
generator client {
provider = "prisma-client-js"
}
model Customer {
id Int @id @default(autoincrement())
name String
}
This schema defines our Customer model with an auto-incrementing id and a name field.
3.2 CustomerService.ts
import type { PrismaClient } from "@prisma/client";
class CustomerService {
private prisma: PrismaClient;
constructor(prisma: PrismaClient) {
this.prisma = prisma;
}
async getAllCustomers() {
return this.prisma.customer.findMany();
}
async getCustomerById(id: number) {
return this.prisma.customer.findUnique({
where: { id },
});
}
async createCustomer(name: string) {
return this.prisma.customer.create({
data: { name },
});
}
async updateCustomer(id: number, name: string) {
return this.prisma.customer.update({
where: { id },
data: { name },
});
}
async deleteCustomer(id: number) {
return this.prisma.customer.delete({
where: { id },
});
}
}
export default CustomerService;
This CustomerService
class provides methods for CRUD operations on customer data, using Prisma ORM to interact with the database.
4. Writing Tests with Bun
Bun comes with a built-in testing framework that’s similar to Jest. Here’s how we write our tests in CustomerService.test.ts
:
import { describe, it, expect, beforeEach, mock } from "bun:test";
import { PrismaClient } from "@prisma/client";
import CustomerService from "../services/CustomerService";
// Mock Customers
const mockCustomers = [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Doe" },
];
// Mock PrismaClient
const prismaMock = {
customer: {
findMany: mock(() => mockCustomers),
findUnique: mock((query) =>
mockCustomers.find((c) => c.id === query.where.id)
),
create: mock((query) => {
const customer = {
id: mockCustomers.length + 1,
name: query.data.name,
};
mockCustomers.push(customer);
return customer;
}),
update: mock((query) => {
const customer = mockCustomers.find((c) => c.id === query.where.id);
if (customer) {
customer.name = query.data.name;
}
}),
delete: mock((query) => {
const index = mockCustomers.findIndex((c) => c.id === query.where.id);
if (index !== -1) {
mockCustomers.splice(index, 1);
}
}),
},
};
mock.module("@prisma/client", () => {
return { PrismaClient: mock(() => prismaMock) };
});
const prisma = new PrismaClient();
const customerService = new CustomerService(prisma);
describe("CustomerService", () => {
beforeEach(() => {
prismaMock.customer.findMany.mockClear();
prismaMock.customer.findUnique.mockClear();
prismaMock.customer.create.mockClear();
prismaMock.customer.update.mockClear();
prismaMock.customer.delete.mockClear();
});
it("should fetch all customers", async () => {
const customers = await customerService.getAllCustomers();
expect(customers).toEqual(mockCustomers);
expect(prismaMock.customer.findMany).toHaveBeenCalledTimes(1);
});
it("should fetch a customer by ID", async () => {
const customer = await customerService.getCustomerById(1);
expect(customer).toEqual(mockCustomers[0]);
expect(prismaMock.customer.findUnique).toHaveBeenCalledWith({
where: { id: 1 },
});
});
it("should create a customer", async () => {
const customer = await customerService.createCustomer("Alice Doe");
expect(customer.id).toEqual(3);
expect(prismaMock.customer.create).toHaveBeenCalledWith({
data: { name: "Alice Doe" },
});
});
it("should update a customer", async () => {
await customerService.updateCustomer(1, "James Doe");
expect(mockCustomers[0].name).toEqual("James Doe");
expect(prismaMock.customer.update).toHaveBeenCalledWith({
where: { id: 1 },
data: { name: "James Doe" },
});
});
it("should delete a customer", async () => {
await customerService.deleteCustomer(1);
expect(mockCustomers.find((t) => t.id === 1)).not.toBeDefined();
expect(prismaMock.customer.delete).toHaveBeenCalledWith({
where: { id: 1 },
});
});
});
5. Mock a module jest-like for the Prisma Client
To mock the Prisma client, we create a mock object that mimics the structure and methods of the real PrismaClient. We use Bun’s mock
function to create mock implementations of the methods we want to test.
The key part of our mocking strategy is:
mock.module("@prisma/client", () => {
return { PrismaClient: mock(() => prismaMock) };
});
This mocks the entire @prisma/client
module, replacing the PrismaClient
with our mock implementation. This allows us to test our CustomerService without actually interacting with a database.
6. Running Tests
To run the tests, use the following command:
bun test
Bun will automatically detect and run all test files in your project.

7. Conclusion
In this tutorial, we’ve learned how to mock a module Jest-style while using Bun’s built-in testing framework. We’ve set up tests for a CustomerService, demonstrating how to mock the Prisma client for efficient testing without real database interactions.
Key takeaways:
- We use Bun’s
mock
function to create mock implementations of Prisma methods. - We mock the entire
@prisma/client
module to replace the real PrismaClient with our mock. - We write tests for each method of our CustomerService, ensuring they interact correctly with the mocked Prisma client.
By using Bun’s testing capabilities, we can streamline our development process and take advantage of Bun’s speed and efficiency. This approach allows for fast, reliable tests that don’t depend on external services, making our test suite more robust and easier to maintain.