如何测试 Nestjs 拦截器?
Posted
技术标签:
【中文标题】如何测试 Nestjs 拦截器?【英文标题】:How to test Nestjs interceptor? 【发布时间】:2020-01-03 21:47:00 【问题描述】:我找不到任何关于如何在 NestJS 中测试拦截器的解释
这个简单的例子截取了一个 POST 查询以向正文中提供的示例模型添加一个属性。
@Injectable()
export class SubscriberInterceptor implements NestInterceptor
async intercept(
context: ExecutionContext,
next: CallHandler,
): Promise<Observable<ExampleModel>>
let body: ExampleModel = context.switchToHttp().getRequest().body;
body =
...body,
addedAttribute: 'example',
;
context.switchToHttp().getRequest().body = body;
return next.handle();
我想测试拦截函数中发生了什么。
到目前为止:
const interceptor = new SubscriberInterceptor();
describe('SubscriberInterceptor', () =>
it('should be defined', () =>
expect(interceptor).toBeDefined();
);
describe('#intercept', () =>
it('should add the addedAttribute to the body', async () =>
expect(await interceptor.intercept(arg1, arg2)).toBe( ...bodyMock, addedAttribute: 'example' );
);
);
);
我的问题:我应该只模拟 arg1: ExecutionContext
和 arg2: CallHandler
吗?如果是这样,如何模拟arg1
和arg2
?否则我应该如何进行?
【问题讨论】:
【参考方案1】:你是对的,你应该模拟arg1
和arg2
,然后将它们传递给intercept
方法,这里是解决方案:
SubscriberInterceptor.ts
:
interface ExecutionContext
switchToHttp(): any;
interface CallHandler
handle(): any;
interface Observable<T>
interface ExampleModel
interface NestInterceptor
intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<ExampleModel>>;
export class SubscriberInterceptor implements NestInterceptor
public async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<ExampleModel>>
let body: ExampleModel = context.switchToHttp().getRequest().body;
body =
...body,
addedAttribute: 'example'
;
context.switchToHttp().getRequest().body = body;
return next.handle();
单元测试,executionContext
的模拟链式方法
import SubscriberInterceptor from './';
const interceptor = new SubscriberInterceptor();
const executionContext =
switchToHttp: jest.fn().mockReturnThis(),
getRequest: jest.fn().mockReturnThis()
;
const callHandler =
handle: jest.fn()
;
describe('SubscriberInterceptor', () =>
it('should be defined', () =>
expect(interceptor).toBeDefined();
);
describe('#intercept', () =>
it('t1', async () =>
(executionContext.switchToHttp().getRequest as jest.Mock<any, any>).mockReturnValueOnce(
body: data: 'mocked data'
);
callHandler.handle.mockResolvedValueOnce('next handle');
const actualValue = await interceptor.intercept(executionContext, callHandler);
expect(actualValue).toBe('next handle');
expect(executionContext.switchToHttp().getRequest().body).toEqual(
data: 'mocked data',
addedAttribute: 'example'
);
expect(callHandler.handle).toBeCalledTimes(1);
);
);
);
单元测试结果:
PASS src/mock-function/57730120/index.spec.ts
SubscriberInterceptor
✓ should be defined (10ms)
#intercept
✓ t1 (11ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.235s, estimated 3s
【讨论】:
当 getRequest 不是 ExecutionContext 的方法时,它是如何工作的?它是从 switchtoHttp() 返回的对象的方法。以上是关于如何测试 Nestjs 拦截器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 NestJS 拦截器中获取处理程序路由(对于 Express 和 Fastify)