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

NestJS注册测试抛出BadRequestException: email in use异常求助

问题排查与修复

核心问题分析

  1. 模拟返回值不符合实际逻辑:你的fakeUsersService中findWithMail返回空数组[],但真实业务里user.service.ts的findWithMail调用的是userRepository.findOne(),该方法仅返回单个用户对象或null,不会返回数组。JavaScript中空数组属于真值,所以auth.service.ts里的if(users)条件会触发,直接抛出"email in use"异常。
  2. 测试用例逻辑颠倒:当前测试用例描述是验证"邮箱已存在时抛出错误",但你模拟的却是邮箱不存在的场景,逻辑完全不匹配。

分步修复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:39:20