NestJS单元测试Mock自定义Mongoose Repository提示不存在如何解决
问题排查与解决方案
- 核对注入Token一致性
检查AssetService构造函数中注入AssetRepository的写法:- 如果使用了
@Inject(自定义Token)装饰器注入,测试代码中provide的取值必须和自定义Token完全一致,不能直接使用AssetRepository类作为provide值 - 如果直接通过类名注入,确认自定义的
AssetRepository类本身添加了@Injectable()装饰器
- 如果使用了
- 简化Mock写法,避免无关依赖干扰
测试单个Service时无需引入其他依赖的真实实例,直接Mock所有非待测依赖即可,避免其他依赖的注入问题连带报错。 - 修正Mock语法与返回值
- 业务代码中调用的
assetRepository.find是异步方法,原Mock返回同步数组会导致后续逻辑异常,调整为返回Promise的写法 module.get()为同步方法,无需添加多余的await
- 业务代码中调用的
调整后的完整测试代码参考:
describe('AssetService', () => { let assetService: AssetService; let assetRepository: AssetRepository; beforeEach(async () => { const module = await Test.createTestingModule({ providers: [ AssetService, // 直接用useValue定义Mock,无需冗余的useFactory { provide: AssetRepository, useValue: { find: jest.fn().mockResolvedValue([]) } }, // 其他非待测依赖全部Mock空实现即可 { provide: TenantProfileService, useValue: {} }, { provide: ProfileUserService, useValue: {} }, { provide: TenantsService, useValue: {} }, { provide: UsersService, useValue: {} }, ], }).compile(); assetService = module.get(AssetService); assetRepository = module.get(AssetRepository); }); describe('getAssets', () => { it('call assetRepository.find and should return all assets', async () => { const result = await assetService.findAll(null, null); expect(assetRepository.find).toHaveBeenCalled(); }); }) })
如果以上调整后仍有报错,可确认测试代码中导入的AssetRepository路径与业务代码中导入的路径完全一致,避免因路径别名、大小写差异导致注入的不是同一个类。
内容的提问来源于stack exchange,提问作者Ramdani Muksin
相关产品推荐
相关产品推荐

