如何为含事务EntityManager的NestJS服务编写单元测试?
单元测试编写方案
首先明确你的create函数核心逻辑:它仅接收EntityManager实例并调用其save方法,事务的创建与管理是在控制器层实现的。因此单元测试无需涉及真实数据库事务,只需模拟EntityManager的行为即可。
问题代码回顾
service.service.ts中的create函数
import { Service } from './entity/service.entity'; import { EntityManager } from 'typeorm'; async create( transactionalEntityManager: EntityManager, data: any ): Promise<Service> { return transactionalEntityManager.save(Service, data); }
service.controller.ts中的POST路由
import { EntityManager, getConnection } from 'typeorm'; import { Service } from './entity/service.entity'; @Post() async createService( @Body() body: ServiceDto, const user = { user_id: 1, company_id: 2 } ): Promise<Service> { return getConnection().transaction(async (t: EntityManager) => this.service.create(t, { ...body, company_id: user.company_id, added_by: user.user_id, }) ); }
单元测试实现(基于Jest)
测试文件service.service.spec.ts
import { Service } from './entity/service.entity'; import { ServiceService } from './service.service'; import { EntityManager } from 'typeorm'; describe('ServiceService', () => { let service: ServiceService; let mockEntityManager: Partial<EntityManager>; beforeEach(() => { // 模拟EntityManager的save方法 mockEntityManager = { save: jest.fn().mockResolvedValue({ id: 1, name: '测试服务', company_id: 2, added_by: 1 }) }; service = new ServiceService(); }); it('应通过传入的事务EntityManager创建服务', async () => { const testData = { name: '测试服务', company_id: 2, added_by: 1 }; const result = await service.create(mockEntityManager as EntityManager, testData); // 验证save方法被正确调用 expect(mockEntityManager.save).toHaveBeenCalledWith(Service, testData); // 验证返回结果符合预期 expect(result).toEqual({ id: 1, ...testData }); }); });
核心要点
- 剥离事务依赖:
create函数不负责事务创建,测试时无需连接真实数据库或启动事务,只需模拟传入的EntityManager实例。 - 聚焦函数职责:单元测试只需验证
save方法是否以正确参数调用,以及返回值是否符合预期,无需关心事务的具体实现。 - 分层测试:控制器层的事务逻辑应单独测试,比如模拟
getConnection().transaction,验证回调中是否正确调用了service.create。
内容的提问来源于stack exchange,提问作者Dilli Chalise
相关产品推荐
相关产品推荐

