简体   繁体   English

使用 axios 对拦截器进行单元测试会引发错误

[英]unit testing the interceptor with axios throws error

I'm writing Unit test for my Nestapp.我正在为我的 Nestapp 编写单元测试。 For the interceptor file, I'm writing a test case to throw an error when error.message.indexOf('timeout') >= 0 and call Axios.Cancel with the error message.对于拦截器文件,我正在编写一个测试用例以在error.message.indexOf('timeout') >= 0时抛出错误并使用错误消息调用Axios.Cancel

But in my spec file I get : Cannot read property 'intercept' of undefined PFB my code and what am I missing here?但在我的规范文件中,我得到: Cannot read property 'intercept' of undefined PFB 的Cannot read property 'intercept' of undefined我的代码,我在这里遗漏了什么?

Can provide any mocks if required!如果需要,可以提供任何模拟!

timeout.interceptor.ts timeout.interceptor.ts

import {
    Injectable,
    NestInterceptor,
    CallHandler,
    HttpCode
} from '@nestjs/common';
import {
    Observable
} from 'rxjs';
import Axios from 'axios';


@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
    intercept(context: any, next: CallHandler): Observable <any> {

        const CancelToken = Axios.CancelToken;
        const source = CancelToken.source();

        const url: string = context.url ? context.url : context.args[0].url;
        Axios.defaults.timeout = 200;


        Axios.get(url, {
            cancelToken: source.token
        }).then((res) => {}, error => {
            if (error.message.indexOf('timeout') >= 0) {
                throw new Axios.Cancel('Operation canceled due to timeout!');
            }
        }).catch((error) => {
            if (Axios.isCancel(error)) {
                console.log('Request canceled ', error);
            } else {
                console.log('--else part--');
            }
        });
        return next.handle();
    }
}
timeout.interceptor.spec.ts timeout.interceptor.spec.ts
 import { Test, TestingModule } from '@nestjs/testing'; import { HttpModule, Controller, ExecutionContext, Get, InternalServerErrorException } from '@nestjs/common'; import { of , Observable, throwError } from 'rxjs'; //import { Reflector } from '@nestjs/core'; import Axios from 'axios'; describe('Content Service', () => { let module: TestingModule; //let reflector; let timeoutInterceptor; //const loggerSpy = jest.fn() let getSpy; let cancelSpy; const errCode = 'MockController#decorated'; const errMessage = 'Controller threw an error'; beforeEach(async () => { module = await Test.createTestingModule({ imports: [HttpModule], }).compile(); getSpy = jest.spyOn(Axios, 'get'); timeoutInterceptor = new timeoutInterceptor(); }) it('should call Axios.Cancel when it catches an timeout>0', done => { const context = { url: '' } timeoutInterceptor.intercept(context, throwError(new InternalServerErrorException())) .subscribe( () => {}, () => { expect(Axios.Cancel).toHaveBeenCalled(); done(); } ) .unsubscribe(); }); });

You shouldn't use axios directly but nest's HttpService instead.您不应该直接使用axios ,而应该使用 nest 的HttpService Then it becomes much easier to test.然后它变得更容易测试。

You can inject the HttpService via your interceptor's constructor:您可以通过拦截器的构造函数注入HttpService

export class TimeoutInterceptor implements NestInterceptor {
  constructor(httpService: HttpService) {}

This makes it much easier to test because you can use a mock for the HttpService (which is just a wrapper for axios ) when you create an instance of your TimeoutInterceptor .这使得测试变得更加容易,因为当您创建TimeoutInterceptor的实例时,您可以使用HttpService的模拟(它只是axios的包装器)。

const httpMock = jest.fn(() => ({
  get: jest.fn(),
}))();
const interceptor = new TimeoutInterceptor(httpMock);

// mocked response
httpMock.get.mockReturnValue({...});
expect(interceptor.intercept(...)).toBe({...});
expect(httpMock.get).toHaveBeenCalled();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM