I would like to log the incoming requests and outgoing responses for my API. I created a request interceptor and a response interceptor as described here
https://docs.nestjs.com/interceptors
So the request interceptor only logs the request object
@Injectable()
export class RequestInterceptor implements NestInterceptor {
private readonly logger: Logger = new Logger(RequestInterceptor.name, true);
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const { originalUrl, method, params, query, body } = context.switchToHttp().getRequest();
this.logger.debug({ originalUrl, method, params, query, body }, this.intercept.name);
return next.handle();
}
}
and the response interceptor waits for the outgoing response and logs the status code and response object later on
@Injectable()
export class ResponseInterceptor implements NestInterceptor {
private readonly logger: Logger = new Logger(ResponseInterceptor.name, true);
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const { statusCode } = context.switchToHttp().getResponse();
return next.handle().pipe(
tap((responseData: any) =>
this.logger.debug({ statusCode, responseData }, this.intercept.name),
),
);
}
}
I would like to test them but unfortunately have almost no experience in testing. I tried to start with the request interceptor and came up with this
const executionContext: any = {
switchToHttp: jest.fn().mockReturnThis(),
getRequest: jest.fn().mockReturnThis(),
};
const nextCallHander: CallHandler<any> = {
handle: jest.fn(),
};
describe('RequestInterceptor', () => {
let interceptor: RequestInterceptor;
beforeEach(() => {
interceptor = new RequestInterceptor();
});
describe('intercept', () => {
it('should fetch the request object', (done: any) => {
const requestInterception: Observable<any> = interceptor.intercept(executionContext, nextCallHander);
requestInterception.subscribe({
next: value => {
// ... ??? ...
},
error: error => {
throw error;
},
complete: () => {
done();
},
});
});
});
});
I currently don't know what to pass into the next callback but when I try to run the test as it is it says that the requestInterception variable is undefined. So the test fails before reaching the next callback. So the error message I get is
TypeError: Cannot read property 'subscribe' of undefined
I also tried to test the response interceptor and came up with this
const executionContext: any = {
switchToHttp: jest.fn().mockReturnThis(),
getResponse: jest.fn().mockReturnThis()
};
const nextCallHander: CallHandler<any> = {
handle: jest.fn()
};
describe("ResponseInterceptor", () => {
let interceptor: ResponseInterceptor;
beforeEach(() => {
interceptor = new ResponseInterceptor();
});
describe("intercept", () => {
it("should fetch the statuscode and response data", (done: any) => {
const responseInterception: Observable<any> = interceptor.intercept(
executionContext,
nextCallHander
);
responseInterception.subscribe({
next: value => {
// ...
},
error: error => {
throw error;
},
complete: () => {
done();
}
});
});
});
});
This time I get an error at the interceptor
TypeError: Cannot read property 'pipe' of undefined
Would some mind helping me to test those two interceptors properly?
Thanks in advance