尝试按照描述编写单元测试 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/