NestJS注册测试抛出BadRequestException: email in use异常求助
问题排查与修复
核心问题分析
- 模拟返回值不符合实际逻辑:你的
fakeUsersService中findWithMail返回空数组[],但真实业务里user.service.ts的findWithMail调用的是userRepository.findOne(),该方法仅返回单个用户对象或null,不会返回数组。JavaScript中空数组属于真值,所以auth.service.ts里的if(users)条件会触发,直接抛出"email in use"异常。 - 测试用例逻辑颠倒:当前测试用例描述是验证"邮箱已存在时抛出错误",但你模拟的却是邮箱不存在的场景,逻辑完全不匹配。
分步修复
1. 修正测试中的模拟返回值
调整fakeUsersService的findWithMail返回值,匹配findOne的实际行为:
// 邮箱不存在时返回null,符合findOne的返回规则 fakeUsersService = { findWithMail: () => Promise.resolve(null), create: (email:string,password:string) => Promise.resolve({email,password} as User), }
2. 调整测试用例,覆盖两种核心场景
场景1:验证邮箱未被使用时可正常注册
it('allows signup with unused email', async () => { const user = await service.signup('asdf@asdf.com', 'asdf'); expect(user).toBeDefined(); expect(user.email).toBe('asdf@asdf.com'); });
场景2:验证邮箱已存在时抛出异常
临时覆盖模拟方法,返回已存在的用户对象,验证异常行为:
it('throws an error if user signs up with email that is in use', async () => { fakeUsersService.findWithMail = () => Promise.resolve({ email: 'asdf@asdf.com' } as User); await expect(service.signup('asdf@asdf.com', 'asdf')).rejects.toThrow(BadRequestException); await expect(service.signup('asdf@asdf.com', 'asdf')).rejects.toThrow('email in use'); });
3. (可选)优化AuthService的判断逻辑
虽然当前逻辑对findOne的返回值(null/用户对象)有效,但可以添加更明确的判断,避免后续混淆:
// auth.service.ts const user = await this.userService.findWithMail(email); if (user) { // 明确判断是否存在用户对象 throw new BadRequestException('email in use'); }
完整修正后的测试代码
let service: AuthService; let fakeUsersService: Partial<UserService>; describe('Auth Service', () => { beforeEach(async () => { fakeUsersService = { findWithMail: () => Promise.resolve(null), create: (email: string, password: string) => Promise.resolve({ email, password } as User), }; const module = await Test.createTestingModule({ providers: [AuthService, { provide: UserService, useValue: fakeUsersService }], }).compile(); service = module.get(AuthService); }); it('can create an instance of auth service', async () => { expect(service).toBeDefined(); }); it('allows signup with unused email', async () => { const user = await service.signup('asdf@asdf.com', 'asdf'); expect(user).toBeDefined(); expect(user.email).toBe('asdf@asdf.com'); }); it('throws an error if user signs up with email that is in use', async () => { fakeUsersService.findWithMail = () => Promise.resolve({ email: 'asdf@asdf.com' } as User); await expect(service.signup('asdf@asdf.com', 'asdf')).rejects.toThrow(BadRequestException); await expect(service.signup('asdf@asdf.com', 'asdf')).rejects.toThrow('email in use'); }); });
内容的提问来源于stack exchange,提问作者MUSTAFA KENDİGÜZEL
相关产品推荐
相关产品推荐

