I'm trying to test an HttpInterceptor
, with the help of ng-mocks
:
@Injectable()
export class AuthTokenInterceptor implements HttpInterceptor {
constructor(private store: Store) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const currentToken = this.store.selectSnapshot(state => state.accounts.accessToken);
if (currentToken) {
req = req.clone({
setHeaders: { Authorization: `Bearer ${currentToken}` },
});
}
return next.handle(req);
}
}
I'm having trouble to see how I could provide the next
parameter, especially since I want to check that the object has the setHeaders property present(or not):
describe('Unauth guard test', () => {
beforeEach(() => {
return MockBuilder(AuthTokenInterceptor, AppModule).mock(Store);
});
it('should allow access if not authenticated', () => {
//Arrange
const fakeToken = 'fakeToken';
const storeDispatchSpy = MockInstance(Store, 'selectSnapshot', jasmine.createSpy().and.returnValue(fakeToken));
const httpHandlerSpy = MockInstance(HttpHandler, 'handle', jasmine.createSpy().and.returnValue(fakeToken));
const fixture = MockRender(AuthTokenInterceptor);
const interceptor = fixture.point.componentInstance;
const request = new HttpRequest('GET', 'http://localhost:4200/');
//Act
const result = interceptor.intercept(request, httpHandlerSpy.???);//How to provide a mock of HttpHandler?
//Assert
expect(storeDispatchSpy).toHaveBeenCalled();
expect(httpHandlerSpy).toHaveBeenCalledOnceWith(???);//How to verify that one parameter of the HttpRequest is set to specific value?
});
});
But how to provide a mocked instance to the intercept method? and more complex, how to check that my spy have been called with an object that has a specific value?
CodePudding user response:
In your case, you need to provide mockStore
isolate your interceptor from other interceptors.
An example from ng-mocks
docs and http interceptors.
https://codesandbox.io/s/intelligent-stallman-9bwup0?file=/src/test.spec.ts
describe('AuthTokenInterceptor', () => {
beforeEach(() => {
return (
MockBuilder(AuthTokenInterceptor, AppModule)
// required for interceptors
.exclude(NG_MOCKS_INTERCEPTORS)
.keep(HTTP_INTERCEPTORS)
.replace(HttpClientModule, HttpClientTestingModule)
);
});
it('adds header', () => {
// creating an empty fixture
const fixture = MockRender('', null, false);
// stubbing store
const store = ngMocks.findInstance(Store);
ngMocks.stubMember(store, 'selectSnapshot', callback =>
callback({
accounts: {
accessToken: 'Testing',
},
}),
);
// render
fixture.detectChanges();
// instances to test how HttpClient uses interceptors
const client = ngMocks.findInstance(HttpClient);
const httpMock = ngMocks.findInstance(HttpTestingController);
// Let's do a simple request.
client.get('/target').subscribe();
// Now we can assert that a header has been added to the request.
const req = httpMock.expectOne('/target');
req.flush('');
httpMock.verify();
// asserting headers
expect(req.request.headers.get('Authorization')).toEqual(
'Bearer Testing',
);
});
});