Reputation: 83
I am trying Jasmine test cases for the first time in Angular 7. I have a observable which emit data using the next() in the service file. The components subscribe for the observable and use the data. Here is the code in ngOnInit
ngOnInit() {
this.loading = true;
this.subscribe(this.advDirectService.directive$, data => {
this.directives = data;
this.loading = false;
});
this.advDirectService.loadDirective(); }
I am able to expect that loadDirective is called. But when i try to expect this.directives it always say NULL. My component extends a BaseComponent. Please help me learn how to write tests for the code inside subscribe block.
Upvotes: 2
Views: 1971
Reputation: 213
This is how it should be:
let dummy_data = "Some dummy data to be returned by service";
const spyOnInit = spyOn(component, "ngOnInit").and.callThrough();
advDirectService = TestBed.get(<Your Service Name>);
const spyData = spyOn(advDirectService, "directive$")
.and.returnValue(Observable.of(dummy_data));
advDirectService.directive$().subscribe(
success => {
expect(success).toEqual(advDirectService);
}
, (error) => {
expect(error).toBeTruthy();
});
component.ngOnInit();
expect(component.ngOnInit).toHaveBeenCalled(); //write your expect statement here
spyData.calls.reset();
spyOnInit.calls.reset();
Upvotes: 0
Reputation: 186
You need to separate your testing of the service and component. Unit testing is meant to be isolated as much as possible.
Instead of testing if the service works in the component you should use mock data you can pass it in like this and only test the component functions:
it('should test something for the component', () => {
component.directives = mockData;
// run a function that depends on the data and expect a return result
})
on the other hand you need to test the service and it's async call, which you should do in your service .spec.ts file:
it('should test something in the service', (done) => {
this.directive$.subscribe(data => {
expect(data) ... something
done();
})
})
note that we pass in a done parameter to the callback - that indicates that the async testing is finished - otherwise the test will fail with timeout error.
I should warn you though, that async testing can be complicated: you might need to pipe(skip(1)) before your subscription if you expect that the first emit will always be null.
There are other methods of testing observables like marble testing - but I personally haven't looked much into it yet.
Upvotes: 2