I'm trying to test an angular service (based on feathersJS) with the standard angular testing tools (Karma and Jasmine).
As my service make XHR call to a back end (using socket.io), I want to mock those calls to test the service.
I use sinon.js library that provide functionality to create fake server, and this parts works.
My problem is that when I mock the XHR response in my test, there are others XHR requests from webpack that try to load "polyfill.js". This occurs when i call the authenticate method of my service, so because of webpack xhr request, the promise always fallback in the catch code.
See details below, so if anyone can help on solving this "issue" or provide another advices on how to mock XHR requests in Angular/jasmine/karma tests
Note that I think that mocking the global xmlHttpRequest object in browser can be tricky...
Thank you !!
Details:
The full error is :
Error: Socket connection timed out at setTimeout (http://localhost:9876/node_modules/@feathersjs/authentication-client/lib/passport.js?:120:1) at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/polyfills.js:2883:31) at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvokeTask (http://localhost:9876/node_modules/zone.js/dist/zone-testing.js?:319:1) at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/polyfills.js:2882:36) at Zone../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:9876/_karma_webpack_/polyfills.js:2650:47) at ./node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (http://localhost:9876/_karma_webpack_/polyfills.js:2958:34) at ZoneTask.invoke (http://localhost:9876/_karma_webpack_/polyfills.js:2947:48) at timer (http://localhost:9876/_karma_webpack_/polyfills.js:4516:29)"
Note that my service doesn't make this XHR...
Here is my (very simple) test spec in jasmine :
import { AppLoggerService } from '../../logger/app-logger/service/app-logger.service';
import { fakeAsync, async, tick } from '@angular/core/testing';
import { mock, instance, when, deepEqual, verify } from 'ts-mockito';
import { FeathersjsBackendService } from './backend-feathers.service';
import { BackendConfigClass } from 'src/app/shared/models/backend-config.model';
import * as sinon from 'sinon'
describe('Feathers backend service', () => {
var MockLoggerService: AppLoggerService = null
var feathersBackendService: FeathersjsBackendService = null
const fakeURL: string = 'http://localhost/socket.io'
var feathersBackendServiceConfig: BackendConfigClass = { apiEndPoint: fakeURL }
var mockSocketServer: any = null;
// create fake websocket server
beforeAll(() => {
})
beforeEach( () => {
mockSocketServer = sinon.createFakeServer()
mockSocketServer.respondWith(/http:\/\/localhost\/socket\.io\/.*/, function (xhr, id) {
xhr.respond(200, {}, 'authenticate')
})
mockSocketServer.respondWith(/^\/_karma_webpack_.*/, function (xhr, id) {
xhr.respond(200, {}, 'webpack module')
})
MockLoggerService = mock(AppLoggerService)
feathersBackendService = new FeathersjsBackendService(instance(MockLoggerService), feathersBackendServiceConfig)
expect(feathersBackendService).not.toBeNull()
})
afterEach( () => {
mockSocketServer.restore();
})
it('#1 - Should mock authenticate', () => {
var isAuth: boolean = false;
feathersBackendService.authenticate({ strategy: 'anonymous' })
.then((user) => {
isAuth = true;
})
.catch((error) => {
let a = 0;
})
mockSocketServer.respond();
expect(isAuth).toBe(true);
})
})