I am trying to unit test an angular service in my application, which creates socket.io client. My service looks something like this:
export class SocketService {
private name: string;
private host: string = window.location.protocol + "//" + window.location.hostname + ":3000";
socket: io.Socket;
constructor() { }
subscribeEvent(name: string): Observable<IJobResp> {
this.setup(name);
return new Observable(observer => {
this.socket.on('job', val => observer.next(val))
})
}
private setup(name: string) {
this.name = name;
let socketUrl = this.host + "/" + this.name;
this.socket = io.connect(socketUrl);
}
}
So to write my test, I am using the mock-socket library to set up a mock socket.io server. Here is what the test looks like:
describe('SocketService', () => {
let socket;
const mockServer = new Server('http://localhost:3000/');
mockServer.on('connection', server => {
mockServer.emit('job', 'test message 1');
});
(window as any).io = SocketIO;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [JobService]
});
});
it('should xyz, inject([JobService], fakeAsync((service: JobService) => {
service.subscribeEvent('/').subscribe(val => {
expect(val).toEqual('test message 1');
})
})));
});
However, that test throws the error:
Error: Cannot make XHRs from within a fake async test.
If I don't have the fakeAsync
, then the test passes before the assertion in the subscribe()
is processed.
How do I get around this?
Update:
Another approach I have tried is to use async
e.g.
it('should subscribe to dwnTime events', async(inject([JobService], (service: JobService) => {
service.subscribeEvent('line/602').subscribe(val => {
expect(val).toEqual('test 2');
})
})));
Then I get:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
This looks like a timing issue, but I still am not sure why?
Your second approach is the right one as the mock server is a real one, therefore you need to increase the timeout by setting
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
(the value is to be adjusted)anywhere inside the describe function.
Here you can find a full example.