NestJS:如何在 canActivate 中模拟 ExecutionContext
Posted
技术标签:
【中文标题】NestJS:如何在 canActivate 中模拟 ExecutionContext【英文标题】:NestJS: How can I mock ExecutionContext in canActivate 【发布时间】:2020-10-17 02:33:03 【问题描述】:我在 Guard 中间件中模拟 ExecutionContext 时遇到问题。
这是我的 RoleGuard 扩展 JwtGuard
@Injectable()
export class RoleGuard extends JwtAuthGuard
...
async canActivate(context: ExecutionContext): Promise<boolean>
const request = context.switchToHttp().getRequest();
const params = request.params;
...
这就是我在单元测试中尝试的。
let context: ExecutionContext = jest.genMockFromModule('@nestjs/common');
context.switchToHttp = jest.fn().mockResolvedValue(
getRequest: () => (
originalUrl: '/',
method: 'GET',
params: undefined,
query: undefined,
body: undefined,
),
getResponse: () => (
statusCode: 200,
),
);
jest.spyOn(context.switchToHttp(), 'getRequest').mockImplementation(() =>
return Promise.resolve(null);
);
我遇到了这种错误。
Cannot spy the getRequest property because it is not a function; undefined given instead
我希望您建议任何其他模拟上下文的方法。谢谢。
【问题讨论】:
【参考方案1】:当谈到 ExecutionContext
时,根据我要测试的内容,我只提供一个简单的对象,比如
const ctxMock =
switchToHttp: () => (
getRequest: () => (
params: paramsToAdd,
url: 'some url path',
...
),
),
并根据需要使用它。如果我需要访问 jest 函数,我会事先将它们保存到变量中并将上下文的函数分配给变量,然后我可以毫无问题地使用 expect(variable).toHaveBeenCalledTimes(x)
。
另一种选择是使用@golevelup/ts-jest
为您创建类型安全的模拟对象。我已经广泛使用这个库以及我制作的其他库。
【讨论】:
【参考方案2】:请查看此库https://www.npmjs.com/package/@golevelup/ts-jest
然后你可以模拟 ExecutionContext 如下。
import createMock from '@golevelup/ts-jest';
import ExecutionContext from '@nestjs/common';
describe('Mocked Execution Context', () =>
it('should have a fully mocked Execution Context', () =>
const mockExecutionContext = createMock<ExecutionContext>();
expect(mockExecutionContext.switchToHttp()).toBeDefined();
...
);
);
希望对你有帮助
【讨论】:
以上是关于NestJS:如何在 canActivate 中模拟 ExecutionContext的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 路由已弃用:如何检测 CanActivate?
如何在 Angular 中为所有路由(主路由和所有子路由)应用 canActivate 保护