0

我正在尝试为我的 validateUser 函数编写一个有趣的单元测试,但是当我在测试中调用该函数时,我总是得到undefined返回的值。

附加上下文

  • 我使用 nestJS 作为我的 api 框架,我已经模拟了我的用户 findOne 查询函数来返回expectedUserObjHashed
  • 我正在使用bcrypt来处理散列和比较密码,我在这个测试中使用hashSynccompare来自库
  • (不确定这是否是验证的正确方法)但我添加了日志语句以验证我的测试是否将其放入if(result)块中并且没有引发异常。

我猜这是一些异步问题,但我已经尝试了几天每天几个小时,但我不确定它发生在哪里。

// This is the set up for my test
  const saltRounds = 10;
  let hashedPassword: string;
  let expectedUserObjHashed: any;

  beforeAll(() => {
    hashedPassword = hashSync('test123!', saltRounds);
    expectedUserObjHashed = {
      id: 1,
      email: 'test@test.com',
      first_name: 'foo',
      last_name: 'barr',
      password: hashedPassword,
    };
  });
it('should validate password', async () => {
    expect(
      await service.validateUser(
// expectedUserObjUnhashed is a duplicate of expectedUserObjHashed minus having the password property hashed
        expectedUserObjUnhashed.email,
        expectedUserObjUnhashed.password,
      ),
// validatedUserObj is the same as the other UserObj objects but the password property is removed
    ).toStrictEqual(validatedUserObj);
  });
async validateUser(email: string, password: string): Promise<any> {
// findUserByEmail() is mocked in the test to return expectedUserObjHashed (noted above before code blocks)
    const user = await this.userService.findUserByEmail(email);
    if (user !== undefined) {
     compare(password, user.password, function (err, result) {
        if (result) {
          const { password, ...userInfo } = user;
          console.log(userInfo);
          return userInfo;
        } else {
          throw new UnauthorizedException();
        }
      });
    } else {
      throw new BadRequestException();
    }
  }

更新:我写了一个控制器来测试validateUser()邮递员中的函数,它似乎没有得到任何返回值(这可能是测试得到的原因undefined)但就在我记录的bcrypt.compare()回调中(就在行之前)并定义了它,所以现在我不确定为什么回调没有按照指示返回。return userInfouserInfouserInfo

更新2: 我玩弄了我的实现,bcrypt.compare()并让它像这样工作:

...
const isMatch = await compare(password, user.password);
      if (isMatch) {
        const { password, ...userInfo } = user;
        return userInfo;
      } else {
        throw new UnauthorizedException();
      }
...

我仍然想知道为什么我最初的实现对我的知识不起作用。

4

1 回答 1

1
compare(password, user.password, function (err, result) {
 if (result) {
  const { password, ...userInfo } = user;
  console.log(userInfo);
  return userInfo;
 } else {
  throw new UnauthorizedException();
 }

compare 内部的函数是一个回调,在比较完成后起作用。所以 compare 正在触发,它什么也不返回,如果完成,该函数正在运行,所以 console.log 它正在工作,但 return 没有任何效果。当您添加等待时,您实际上是在等待比较完成。

于 2021-01-11T00:35:57.443 回答