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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:18:28