Reputation: 274
I'm writing Unit test for my 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.
But in my spec file I get : Cannot read property 'intercept' of undefined
PFB my code and what am I missing here?
Can provide any mocks if required!
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();
});
});
Upvotes: 1
Views: 3472
Reputation: 60557
You shouldn't use axios
directly but nest's HttpService
instead. Then it becomes much easier to test.
You can inject the HttpService
via your interceptor's constructor:
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
.
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();
Upvotes: 1