unit-testing - 单元测试nestjs守卫未知的身份验证策略

标签 unit-testing testing jestjs passport.js nestjs

尝试按照描述编写单元测试 here但不知道如何解决这个错误

Exception has occurred: Error: Unknown authentication strategy "test-jwt"
  at attempt (/home/user/Workspace/project/node_modules/passport/lib/middleware/authenticate.js:190:39)
    at authenticate

授权文件

import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";

@Injectable()
export class MyGuard extends AuthGuard('test-jwt') { }

测试

import { ExecutionContext } from "@nestjs/common";
import { MyGuard } from "./mygaurd";

it('test' () => {
    const context: ExecutionContext = {
      switchToHttp: () => context,
      getRequest: () => {
        return {
          headers: {
            authorization: `bearer ${jwt}` 
          }
        }
      },
      getResponse: () => { }
    } as unknown as ExecutionContext

    const guard = new MyGuard()

    expect(guard.canActivate(context)).toBeTrue();
})

实际实现工作正常,我将其添加到 Controller 中。

@UseGuards(MyGuard)
export class MyController {

我什至不需要将其添加为提供程序或我的设置中的任何内容,因此不确定要包含哪些其他代码。

我实现了一个可能相关的自定义策略

import { Strategy, ExtractJwt } from "passport-jwt";
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";

@Injectable()
export class MyStrategy extends PassportStrategy(Strategy, 'test-jwt') {
   
  constructor() {
    super({ 
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 
      secretOrKey: 'secret'
    })
  }

  async validate(payload) {
    ...
  }
}

当然,MyStrategy 已作为提供程序添加到我的应用程序中。

我已经有涵盖我的自定义策略的单元测试,所以它实际上只是剩下的守卫

编辑:

尝试下面杰伊的建议让我更接近一点,但我仍然在挣扎。

似乎 passport.use() 需要一个名称和策略而不是一个函数(因此 TS 编译失败),所以我尝试了

import passport, { Strategy } from "passport";
...

passport.use('test-jwt', {
   authenticate: (payload) => true
} as Strategy);

错误消失,但测试现在输出

expect(received).toBeTrue()

Expected value to be true:
  true
Received:
  {}

还有什么建议吗?

最佳答案

这是我从未想过会看到的 Passport 上的奇怪东西之一。那么, Passport 使用策略名称来确定实际使用的身份验证方法,对吧?在一般方案中,所有这些策略都使用passport.use(name, method)注册到passport上下文中。在 Nest 的上下文中,当您创建自定义策略、扩展 PassportStrategy 并将该策略添加为提供程序 as seen here 时,就会发生这种情况。 。稍后,方法 passport.authenticate(strategy, (err, req, res, next) 被调用 during the AuthGuard#canActivate 方法(代码有点复杂,但这就是发生的地方)。因为 Passport 有在测试上下文中从未见过 passport.use('test-jwt', authMethod),它最终除了抛出有关“未知身份验证策略”的错误之外不知道该怎么做。

通常,validate 方法将成为 authMethod,但如果您只需要在测试上下文中使用它,您可以执行类似的操作

it('test' () => {
    passport.use('test-jwt', (payload) => true);
    const context: ExecutionContext = {
      switchToHttp: () => context,
      getRequest: () => {
        return {
          headers: {
            authorization: `bearer ${jwt}` 
          }
        }
      },
      getResponse: () => { }
    } as unknown as ExecutionContext

    const guard = new MyGuard()

    expect(guard.canActivate(context)).toBeTrue();
})

应该可以顺利完成。然后,您可以修改从该方法返回的值,或者将其设为 jest.fn(),以便您可以检查它的调用内容,并在需要进行额外测试时修改它返回的内容守卫。

关于unit-testing - 单元测试nestjs守卫未知的身份验证策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67832906/

相关文章:

java - 验证属性或配置的单元/集成测试

testing - 在 redux Action 测试中出错

javascript - 我觉得大多数用 jest 和 enzyme 进行的组件测试都是毫无值(value)的,我错了吗?

java - 测试我的 Maven 库与 Android 的兼容性

python - 如何从打印消息并关闭程序的函数创建单元测试?

php - Laravel 5 - 单元测试 - 状态码 500,预期 200

ruby-on-rails - ruby 矿 'Unable to attach test reporter to test framework'

javascript - 有没有人成功地使用 react-testing-library 来测试 draftJS Editor 组件上的更改事件?

javascript - 使用 Jest 和 Create React App 模拟全局变量时出现未定义错误

unit-testing - Fluent NHibernate PersistenceSpecification 组件和引用测试