Nest.js模块间DI测试报错:无法找到指定模块
解决Nest.js单元测试中
Cannot find module 'src/foo/foo.module'错误 问题根源
这个错误是Jest的模块解析规则和项目运行时的路径解析不一致导致的:项目运行时(比如通过TSConfig的paths配置)能识别src/开头的路径,但Jest默认不会自动识别这个别名,所以找不到模块。另外你的测试代码存在冗余配置,同时导入了FooModule和手动mock了FooService,这会导致DI容器的依赖冲突。
分步解决方案
1. 配置Jest识别src/路径别名
在项目根目录的jest.config.js(或jest.config.ts)中添加模块映射配置:
module.exports = { // 保留原有其他配置(比如testMatch、transform等) moduleNameMapper: { '^src/(.*)$': '<rootDir>/src/$1', }, // 也可以用modulePaths直接指定src为根路径之一 // modulePaths: ['<rootDir>/src'], };
配置后,Jest就能正确解析src/foo/foo.module这类路径了。
2. 优化测试代码(二选一即可)
方案A:使用真实的FooModule(集成测试风格)
如果需要测试BarService和真实FooService的交互逻辑,直接导入FooModule即可,不需要手动mockFooService:
import { Test, TestingModule } from '@nestjs/testing'; import { FooModule } from 'src/foo/foo.module'; import { BarService } from './bar.service'; describe('BarService', () => { let service: BarService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [BarService], imports: [FooModule], // 导入模块自动提供导出的FooService }).compile(); service = module.get<BarService>(BarService); }); it('should be defined', () => { expect(service).toBeDefined(); }); });
方案B:完全Mock FooService(单元测试风格)
如果只需要测试BarService自身的逻辑,不需要依赖真实的FooService,直接mock即可,无需导入FooModule:
import { Test, TestingModule } from '@nestjs/testing'; import { FooService } from 'src/foo/foo.service'; import { BarService } from './bar.service'; describe('BarService', () => { let service: BarService; let mockFooService: jest.Mocked<FooService>; beforeEach(async () => { // 定义mock实现 mockFooService = { test: jest.fn().mockReturnValue('This is a test'), } as jest.Mocked<FooService>; const module: TestingModule = await Test.createTestingModule({ providers: [ BarService, { provide: FooService, useValue: mockFooService, }, ], }).compile(); service = module.get<BarService>(BarService); }); it('should be defined', () => { expect(service).toBeDefined(); }); // 可添加测试验证mock调用逻辑 it('should invoke FooService.test when calling BarService.someMethod', () => { // 假设BarService有调用FooService.test的方法 service.someMethod(); expect(mockFooService.test).toHaveBeenCalled(); }); });
关键注意点
- 不要同时导入
FooModule和手动mockFooService,这会导致Nest DI容器出现依赖冲突,完全没必要重复配置 - 如果项目使用了TSConfig的
paths配置,确保Jest的moduleNameMapper和TSConfig的paths保持一致
内容的提问来源于stack exchange,提问作者Laszlo Sarvold
相关产品推荐
相关产品推荐

