I'm working on an Angular (v 6.1.0) app which is communicating with a backend over a websocket. So far everything's been working fine except for the unit testing. I've created a mock backend for the purpose of testing my components but I just can't establish a connection between the mock backend and testing modules. I'm using Jasmine as an assertion library and Jest as a test runner, this is a sample test suite:
describe('RandomComponent', () => {
let component: RandomComponent;
let fixture: ComponentFixture<RandomComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [],
imports: [SomeModule],
providers: [SpecialWebSocketService, WebSocketService,
{ provide: BackendUrlService, useClass: BackendUrlMockService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RandomComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create random component', () => {
expect(component).toBeTruthy();
});
});
BackendUrlMockService is there just to provide a URL. The single test case produces the following:
FAIL src/app/path/to/my/random.component.spec.ts
RandomComponent
✕ should create random component (603ms)
● RandomComponent › should create random component
InvalidStateError: Still in CONNECTING state.
Application works fine both with real backend and the mocked one. Testing modules work with neither. I also noticed that if I add a timeout to the test case:
it('should create random component', (done) => {
setTimeout(() => {
expect(component).toBeTruthy();
done();
}, 1000);
});
My mock backend logs a message that connection was established properly but I still get the error. Does anyone have an idea how to set up everything properly so that I could test my components?
Based on @user184994 comment I decided to mock the websocket instead of the backend:
const mockData = {
// some arbitrary data
};
class WebSocketServiceSpy {
private messageSpy = new Subject<string>();
private messageHandler = this.messageSpy.asObservable();
createObservableSocket(url: string): Observable<string> {
console.log(`Websocket would connect to ${url}.`);
return new Observable(observer => {
this.messageHandler.subscribe(() => {
observer.next(JSON.stringify(mockData));
});
});
}
sendMessage(message: any) {
this.messageSpy.next();
}
}
Then, I used it in the testing module:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [],
imports: [SomeModule],
providers: [SpecialWebSocketService, BackendUrlService,
{ provide: WebSocketService, useClass: WebSocketServiceSpy }
]
})
.compileComponents();
}));
And the test is finally green:
PASS src/app/path/to/my/random.component.spec.ts
● Console
console.log src/app/path/to/my/random.component.spec.ts:911
Websocket would connect to <actual url>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With