You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含事务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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:05:25