如何在不修改类构造函数的情况下监视PrismaClient实例?
解决Jest监视内部创建的PrismaClient实例问题
由于你不想修改现有UserRepository类,同时希望在集成测试中验证prisma.users.create的调用参数,可以通过包装PrismaClient类并自动添加调用监视的方式实现,具体步骤如下:
实现思路
通过Jest的jest.doMock方法替换@prisma/client模块的导入,返回一个继承自原始PrismaClient的包装类。在包装类的构造函数中,自动为实例的users.create方法添加监视(同时保留真实的数据库操作逻辑,符合集成测试要求),这样就能捕获UserRepository内部创建的Prisma实例的调用。
测试代码示例
import type { User } from './your-user-type-path'; // 导入你的User类型 describe('UserRepository', () => { let prismaCreateSpy: jest.SpyInstance; beforeEach(async () => { // 包装PrismaClient,自动为新实例添加create方法监视 jest.doMock('@prisma/client', () => { const originalPrisma = jest.requireActual('@prisma/client'); return { ...originalPrisma, PrismaClient: class extends originalPrisma.PrismaClient { constructor(...args: any[]) { super(...args); // 监视users.create方法,保留真实实现 prismaCreateSpy = jest.spyOn(this.users, 'create') .mockImplementation(super.users.create.bind(this)); } } }; }); // 重置模块缓存,确保UserRepository使用包装后的PrismaClient jest.resetModules(); }); afterEach(() => { // 清理所有mock,避免影响其他测试 jest.restoreAllMocks(); }); it('should call prisma.users.create with correct user data', async () => { // 重新导入UserRepository(因为模块缓存已重置) const { UserRepository } = await import('./user-repository'); const userRepo = new UserRepository(); const testUserData: User = { name: '张三', email: 'zhangsan@example.com' }; // 测试用的用户数据 await userRepo.createUser(testUserData); // 验证调用次数和参数 expect(prismaCreateSpy).toHaveBeenCalledTimes(1); expect(prismaCreateSpy).toHaveBeenCalledWith({ data: testUserData }); }); });
注意事项
- 你的
createUser方法存在一个变量名错误:参数是userData,但调用prisma.users.create时传入的是user,这会导致变量未定义,建议修正为:async createUser(userData: User) { const prisma = new PrismaClient(); await prisma.users.create({ data: userData }); } - 确保测试环境中配置了正确的Prisma数据库连接(集成测试需要连接真实数据库)。
内容的提问来源于stack exchange,提问作者RinnieR
相关产品推荐
相关产品推荐

