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

Node.js+TypeScript环境下Jest单元测试Mock时模块找不到错误排查

问题修复方案

一、先解决「Cannot find module」错误

你的业务代码里使用了@app/config/Config路径别名,但当前Jest配置只覆盖了~前缀,未处理@app别名,这是模块找不到的核心原因。

1. 同步TS与Jest的路径别名配置

首先确认你的tsconfig.json里的路径配置(如果没有则添加):

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@app/*": ["*"],
      "~/*": ["*"]
    }
  }
}

2. 更新Jest配置

修改jest.config.js的moduleNameMapper,补充@app的映射规则:

moduleNameMapper: {
  "^~(.*)$": "<rootDir>/src/$1",
  "^@app/(.*)$": "<rootDir>/src/$1"
}

二、修复Config的Mock逻辑

你当前的Mock方式错误,因为Config是convict验证后的实例,不是可直接Mock的普通函数,需要Mock整个Config模块:

1. 正确Mock Config模块

在测试文件顶部替换原有的Config导入与Mock逻辑:

import 'reflect-metadata';
import AppController from '../controllers/AppController';
import { ResponseToolkit, Request } from '@hapi/hapi';
import Config from '../config/Config';

// Mock整个Config模块,替换get方法为jest mock函数
jest.mock('../config/Config', () => ({
  get: jest.fn()
}));

2. 调整测试逻辑,测试真实业务代码

你之前的测试只是验证了mock函数被调用,没有测试getAppDetailsHandler的真实逻辑,调整后的测试文件如下:

import 'reflect-metadata';
import AppController from '../controllers/AppController';
import { ResponseToolkit, Request } from '@hapi/hapi';
import Config from '../config/Config';

jest.mock('../config/Config', () => ({
  get: jest.fn()
}));

// 模拟ResponseToolkit的核心方法
const mockToolkit = {
  response: jest.fn((data) => ({ data }))
} as unknown as ResponseToolkit;

describe('App Routes - V api', () => {
  it('should return version details', async () => {
    const mockedServiceName = 'microservice-template';
    const mockedServiceVersion = '0.0.1';
    const expectedResponse = {
      data: {
        version: mockedServiceName,
        name: mockedServiceVersion
      }
    };

    // 配置Config.get的返回值
    (Config.get as jest.Mock)
      .mockReturnValueOnce(mockedServiceName) // 对应serviceName
      .mockReturnValueOnce(mockedServiceVersion); // 对应serviceVersion

    // 实例化真实的AppController
    const appController = new AppController();
    // 模拟BaseController的buildResponse方法(如果需要)
    appController.buildResponse = jest.fn((h, data) => h.response({ data }));

    const mockRequest = {} as Request;
    const response = await appController.getAppDetailsHandler(mockRequest, mockToolkit);

    // 验证依赖调用与结果正确性
    expect(Config.get).toHaveBeenCalledTimes(2);
    expect(Config.get).toHaveBeenNthCalledWith(1, 'serviceName');
    expect(Config.get).toHaveBeenNthCalledWith(2, 'serviceVersion');
    expect(appController.buildResponse).toHaveBeenCalledWith(mockToolkit, {
      version: mockedServiceName,
      name: mockedServiceVersion
    });
    expect(response).toEqual(expectedResponse);
  });
});

三、额外说明

  • 不要MockAppController本身,除非你要测试依赖它的上层逻辑;测试getAppDetailsHandler时,应该实例化真实的控制器,Mock它的外部依赖(如Config)
  • 确保BaseController的buildResponse和handleErrors方法在测试环境中可被模拟或正常执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:52:38