我编写了一个 Nestjs 示例项目,项目源代码:https://github.com/hantsy/nestjs-graphql-sample 并尝试测试自定义权限保护。
@Injectable()
export class HasPermissionsGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const routePermissions = this.reflector.get<PermissionType[]>(
HAS_PERMISSIONS_KEY,
context.getHandler(),
);
if (!routePermissions || routePermissions.length == 0) {
return true;
}
const { user } = GqlExecutionContext.create(context).getContext()
.req as AuthenticatedRequest;
return (
user.permissions &&
user.permissions.some((r) => routePermissions.includes(r))
);
}
}
当我尝试使用 Jest 测试 HasPermissionsGuard
的逻辑时,
it('should return true if the `HasPermissions` decorator is set', async () => {
const context = mock<ExecutionContext>();
context.getHandler.mockReturnValue({} as any);
// the following will failed.
const host = mock<ExecutionContextHost>();
host.getArgByIndex.mockImplementation((idx: number) => {
return {
req: { user: { permissions: [PermissionType.WRITE_POSTS] } as any },
} as any;
});
const ctx = mock<GqlExecutionContext>();
ctx.getContext.mockReturnValue({
req: { user: { permissions: [PermissionType.WRITE_POSTS] } as any },
});
reflecter.get
.mockReturnValue([PermissionType.WRITE_POSTS])
.calledWith(HAS_PERMISSIONS_KEY, context.getHandler());
const result = await guard.canActivate(context);
expect(result).toBeTruthy();
expect(reflecter.get).toBeCalledTimes(1);
});
我使用了 jest-mock-extended
和 jest
,如何模拟 GqlExecutionContext.create(context).getContext()
?