测试TypeORM Repository的find方法where选项及异常捕获问题
解决TypeORM find方法Mock与异常捕获测试问题
看起来你在测试TypeORM查询的异常捕获逻辑时遇到了两个核心问题:一是你的Mock方法没有根据where参数动态调整返回结果,二是测试断言的方向不对(因为服务方法内部已经捕获了异常,不会向外抛出)。咱们一步步来修复:
问题分析
先拆解下你的代码里的关键问题:
- Mock方法不区分where条件:当前的
mockHistoricalMappingTypesRepo.find不管传入什么where参数,都会返回预设的mockHistoricalTypes数据,所以永远触发不了catch分支。 - 测试断言错误:你的服务方法里已经用
try/catch捕获了异常,并且执行return,不会把错误抛到方法外部,所以expect(mockFn).toThrowError()永远不会成立。 - 测试逻辑无效:你在测试用例里直接调用
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
相关产品推荐
相关产品推荐

