NestJS Mock TypeORM Repository数据源时依赖注入报错求助
解决NestJS测试中Mock TypeORM Repository的依赖注入错误
问题原因
你的测试模块中导入了UserModule,而UserModule内部通过TypeOrmModule.forFeature([UserEntity])注册了真实的Repository,Nest会尝试从TypeOrmModule上下文获取DataSource实例,但测试环境未配置该依赖,因此抛出无法解析UserEntityRepository依赖的错误。
解决方案
方案1:移除UserModule导入,直接Mock Repository
修改测试模块配置,移除UserModule,只提供需要的服务和Mock的Repository:
const mockUserRepositoryFactory = jest.fn(() => ({ findOneBy: jest.fn(), })); describe('JwtStrategy', () => { let jwtStrategy: JwtStrategy; let userService: UserService; let userRepository: Repository<UserEntity>; beforeEach(async () => { const module = await Test.createTestingModule({ providers: [ JwtStrategy, UserService, { provide: getRepositoryToken(UserEntity), useFactory: mockUserRepositoryFactory, }, ], }).compile(); jwtStrategy = module.get<JwtStrategy>(JwtStrategy); userService = module.get<UserService>(UserService); userRepository = module.get<Repository<UserEntity>>(getRepositoryToken(UserEntity)); }); describe('validate', () => { it('validates and returns user based on JWT payload', async () => { const testUser = new UserEntity(); testUser.username = 'TestUser'; userRepository.findOneBy.mockResolvedValue(testUser); const result = await jwtStrategy.validate({ username: 'TestUser' }); expect(userRepository.findOneBy).toHaveBeenCalledWith({ username: 'TestUser' }); expect(result).toEqual(testUser); }); it('throws an unauthorized exception as user cannot be found', async () => { userRepository.findOneBy.mockResolvedValue(null); await expect(jwtStrategy.validate({ username: 'TestUser' })).rejects.toThrow(UnauthorizedException); }); }); });
方案2:直接Mock UserService(更简洁)
因为JwtStrategy直接依赖的是UserService,不需要关心UserService内部的Repository实现,所以可以直接MockUserService:
const mockUserService = { findOneBy: jest.fn(), }; describe('JwtStrategy', () => { let jwtStrategy: JwtStrategy; let userService: typeof mockUserService; beforeEach(async () => { const module = await Test.createTestingModule({ providers: [ JwtStrategy, { provide: UserService, useValue: mockUserService, }, ], }).compile(); jwtStrategy = module.get<JwtStrategy>(JwtStrategy); userService = module.get<UserService>(UserService); }); describe('validate', () => { it('validates and returns user based on JWT payload', async () => { const testUser = new UserEntity(); testUser.username = 'TestUser'; userService.findOneBy.mockResolvedValue(testUser); const result = await jwtStrategy.validate({ username: 'TestUser' }); expect(userService.findOneBy).toHaveBeenCalledWith({ username: 'TestUser' }); expect(result).toEqual(testUser); }); it('throws an unauthorized exception as user cannot be found', async () => { userService.findOneBy.mockResolvedValue(null); await expect(jwtStrategy.validate({ username: 'TestUser' })).rejects.toThrow(UnauthorizedException); }); }); });
关键说明
- 测试单一服务(如
JwtStrategy)时,应只提供该服务直接依赖的组件,避免导入完整模块导致真实依赖被初始化 - 使用
getRepositoryToken(UserEntity)确保Mock的Repository能正确替换TypeORM自动生成的Repository实例 - 若测试层级仅关注当前服务的逻辑,直接Mock上层依赖(如
UserService)会让测试更聚焦,减少不必要的Mock细节
内容的提问来源于stack exchange,提问作者Remi
相关产品推荐
相关产品推荐

