【问题标题】:unit testing the interceptor with axios throws error使用 axios 对拦截器进行单元测试会引发错误
【发布时间】:2019-09-12 22:45:03
【问题描述】:

我正在为我的 Nestapp 编写单元测试。对于拦截器文件,我正在编写一个测试用例以在error.message.indexOf('timeout') >= 0 和调用Axios.Cancel 时抛出错误消息。

但在我的规范文件中我得到:Cannot read property 'intercept' of undefined PFB 我的代码,我在这里缺少什么?

如果需要,可以提供任何模拟!

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
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();
    });

});

【问题讨论】:

  • 还有未解决的问题吗? :)

标签: javascript node.js typescript jestjs nestjs


【解决方案1】:

您不应该直接使用axios,而是使用嵌套的HttpService。这样测试就容易多了。

您可以通过拦截器的构造函数注入HttpService

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

这使得测试变得更加容易,因为您可以在创建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();

【讨论】:

    猜你喜欢
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 2019-04-28
    • 2021-11-05
    • 2019-06-29
    相关资源
    最近更新 更多