I'm working on my unit test cases for Angular 2 with Karma, I got stuck with one of a function where I run the test for below line
expect(component.subscribeToEvents()).toBeTruthy();
and I view my coverage code, the lines inside the test file seems not covering anything inside the subscribe. I have tried using MockBackend in mocking the api call inside a function on service but I'm not sure how to do the mocking on a subscribed object, can somebody please help me?
The below is in test.component.ts
subscribeToEvents() {
this.subscription = this.czData.$selectedColorZone
.subscribe(items => {
this.resourceLoading = true;
if (!this.resourceData || (this.resourceData && this.resourceData.length === 0)) {
this.settings.layout.flypanel.display = false;
this.getAllResources(this.pagination.start, this.pagination.size);
}
else {
this.pagination.start = 1;
this.pagination.end = this.pagination.size;
this.getAllResources(1, this.pagination.size);
this.settings.layout.flypanel.display = true;
}
});
return true;
}
You can't do this, as the subscription is resolved asynchronously. So the synchronous test completes before the async task is resolved.
If all you want is coverage, you can just make the test
async
. This will cause the Angular test zone to wait until the async task is resolved, before completing the testYou can't try to expect anything here, as there is no callback hook for when the task is resolved. So this is really a pointless test. It will give you coverage, but you aren't actually testing anything. For instance, you might want to test that the variables are set when the subscription is resolved.
Based on the code provided, what I would do instead is just mock the service, and make it synchronous. How can you do that? We you can make the mock something like
Then just configure it in the test
Now in your tests, you don't need to make it
async
, and you can provide any value you want by just setting theitems
property on the mock, and subscriber will get itUPDATE
I think I was half asleep when I wrote this post. One of the above statements is incorrect
This is not completely true. This is what
fixture.whenStable()
is for. For instance if this is your serviceThen this is how you would make the test work
We use
fixture.whenStable()
to to wait for the async tasks to complete.This is not to say that using the mock is wrong. A lot of the time, using the mock would be the way to go. I just wanted to correct my statement, and show how it could be done.