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

测试TypeORM Repository的find方法where选项及异常捕获问题

解决TypeORM find方法Mock与异常捕获测试问题

看起来你在测试TypeORM查询的异常捕获逻辑时遇到了两个核心问题:一是你的Mock方法没有根据where参数动态调整返回结果,二是测试断言的方向不对(因为服务方法内部已经捕获了异常,不会向外抛出)。咱们一步步来修复:

问题分析

先拆解下你的代码里的关键问题:

  1. Mock方法不区分where条件:当前的mockHistoricalMappingTypesRepo.find不管传入什么where参数,都会返回预设的mockHistoricalTypes数据,所以永远触发不了catch分支。
  2. 测试断言错误:你的服务方法里已经用try/catch捕获了异常,并且执行return,不会把错误抛到方法外部,所以expect(mockFn).toThrowError()永远不会成立。
  3. 测试逻辑无效:你在测试用例里直接调用mockHistoricalMappingTypesRepo.find({ where: { HistoricalMappingType: 'Testing' }, }),这不会影响服务实例使用的Mock对象,相当于白调用了。

修复方案

步骤1:改造Mock的find方法,支持动态返回

我们需要让Mock的find方法根据传入的where参数判断,当匹配不到预期条件时抛出错误:

const mockHistoricalTypes: HistoricalTypes[] = [
  { HistoricalTypeID: 1, HistoricalType: 'Contracts' },
];

// 改造Mock,根据where参数动态处理
const mockHistoricalMappingTypesRepo = {
  find: (options: { where: { HistoricalType: string } }) => {
    if (options.where.HistoricalType === 'Contracts') {
      return Promise.resolve(mockHistoricalTypes);
    } else {
      // 查询不到时抛出错误,模拟TypeORM的查询异常
      return Promise.reject(new Error('Entity not found'));
    }
  },
};

步骤2:调整测试用例的逻辑与断言

因为服务方法内部捕获了异常并打日志,不会向外抛错,所以我们需要断言logger的error方法被调用,而不是断言方法抛错。另外,如果你想测试"查询不到Contracts类型"的场景,需要临时替换Mock的find行为:

it('should log error when historical type Contracts is not found', async () => {
  // 先获取并Mock logger(假设你用的是NestJS的Logger,需提前在测试模块注入Mock)
  const logger = module.get<Logger>(Logger);
  const loggerErrorSpy = jest.spyOn(logger, 'error').mockImplementation(() => {});

  // 临时替换Mock的find方法,让它查询Contracts时抛出错误
  jest.spyOn(mockHistoricalMappingTypesRepo, 'find')
    // 模拟数据库查询失败抛出异常
    .mockRejectedValueOnce(new Error('Database query failed'));
    // 如果是模拟返回空数组(需服务逻辑判断空数组为异常的话),用下面这行:
    // .mockResolvedValueOnce([]);

  // 调用服务方法
  await service.ContractHistoricalMapping();

  // 断言logger.error被调用
  expect(loggerErrorSpy).toHaveBeenCalled();
  // 进一步断言调用参数符合预期
  expect(loggerErrorSpy).toHaveBeenCalledWith(
    expect.stringContaining('Historical mapping type contracts could not found'),
    expect.any(String)
  );
});

额外说明

  • 如果你的服务逻辑中,返回空数组不算异常(只有数据库查询失败才会进入catch),那你需要调整服务代码:只有当find抛出错误时才进入catch,空数组的情况要单独处理。
  • 确保你正确Mock了Logger,如果是NestJS的内置Logger,可以在测试模块里提供Mock实例:
{ provide: Logger, useValue: { error: jest.fn() } }

这样调整后,就能正确测试到异常捕获和日志输出的逻辑了。

内容的提问来源于stack exchange,提问作者user3182518

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:14:57