如何脱离Jest使用prisma-mock模拟Prisma,为API控制器传入测试假数据?
不用Jest,基于prisma-mock搭建API控制器的模拟方案
核心逻辑
prisma-mock本质是生成一个模拟的Prisma Client实例,不需要绑定Jest测试框架,直接在Node.js环境初始化后注入到控制器即可,和你使用真实Prisma Client的方式完全一致。
具体实现步骤
1. 安装依赖
npm install prisma-mock @prisma/client
2. 初始化模拟Prisma并填充假数据
// mock-prisma.js const { PrismaClient } = require('@prisma/client'); const { mockDeep } = require('prisma-mock'); // 创建模拟的Prisma Client实例 const mockPrisma = mockDeep(PrismaClient); // 预定义假数据与查询逻辑 mockPrisma.user.findMany.mockResolvedValue([ { id: 1, name: '张三', email: 'zhangsan@example.com' }, { id: 2, name: '李四', email: 'lisi@example.com' } ]); mockPrisma.user.findUnique.mockResolvedValue((args) => { return { id: args.where.id, name: `用户${args.where.id}`, email: `user${args.where.id}@test.com` }; }); // 模拟创建用户的逻辑(带内存数据持久化) let mockUserId = 3; mockPrisma.user.create.mockImplementation((args) => { const newUser = { id: mockUserId++, ...args.data }; // 更新findMany的返回值,模拟数据新增 const currentUsers = mockPrisma.user.findMany.mock.results[0]?.value || []; mockPrisma.user.findMany.mockResolvedValue([...currentUsers, newUser]); return Promise.resolve(newUser); }); module.exports = mockPrisma;
3. 在API控制器中注入模拟实例
假设你的控制器代码如下:
// user-controller.js class UserController { constructor(prisma) { this.prisma = prisma; } async getUsers(req, res) { const users = await this.prisma.user.findMany(); res.status(200).json({ code: 200, data: users }); } async getUserById(req, res) { const user = await this.prisma.user.findUnique({ where: { id: parseInt(req.params.id) } }); if (!user) return res.status(404).json({ code: 404, msg: '用户不存在' }); res.status(200).json({ code: 200, data: user }); } async createUser(req, res) { const newUser = await this.prisma.user.create({ data: req.body }); res.status(201).json({ code: 201, data: newUser }); } } module.exports = UserController;
在API服务中注入模拟Prisma实例:
// server.js const express = require('express'); const UserController = require('./user-controller'); const mockPrisma = require('./mock-prisma'); const app = express(); app.use(express.json()); const userController = new UserController(mockPrisma); app.get('/users', userController.getUsers.bind(userController)); app.get('/users/:id', userController.getUserById.bind(userController)); app.post('/users', userController.createUser.bind(userController)); app.listen(3000, () => { console.log('Mock API服务启动于端口3000'); });
4. 替代方案:手动模拟Prisma Client
如果prisma-mock的使用不符合预期,也可以手动实现一个模拟类,完全复刻Prisma Client的方法签名:
// manual-mock-prisma.js class MockPrisma { constructor() { this.userStore = [ { id: 1, name: '张三', email: 'zhangsan@example.com' } ]; } user = { findMany: () => Promise.resolve([...this.userStore]), findUnique: (args) => Promise.resolve(this.userStore.find(u => u.id === args.where.id)), create: (args) => { const newUser = { id: this.userStore.length + 1, ...args.data }; this.userStore.push(newUser); return Promise.resolve(newUser); } }; } module.exports = new MockPrisma();
直接在控制器中使用这个实例即可,调用方式和真实Prisma Client完全一致。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

