Why isn't my async Angular Jasmine unit test working?
I am trying to test an asynchronous component method and I think I am using Angular 4's asynchronous testing capabilities correctly, but it is not working. My problem is when I run the test, it doesn't wait for the Promise to resolve. It looks like the asynchronous nature of the function is causing a timeout that needs to be disabled and the test should exit prematurely. The test will pass regardless, because all instructions expect()
inside are whenStable()
skipped.
If I omit the wrapper function async()
and switch to the Jasmine syntax to pass in the callback done
and call it at the end of the block whenStable()
, it works correctly. Can anyone tell me why it doesn't work with Angular wrapper async()
?
My code looks like this:
// my.component.ts
ngOnInit() {
this.getResults().then((results) => {
this.results = results;
});
}
// My asynchronous function, which takes 1.5s to load results
getResults() {
let promise = new Promise((resolve) => {
setTimeout(() => {
resolve('foo');
}, 1500);
})
return promise;
}
// my.component.spec.ts (Angular async version which doesn't work)
it('should load results', async(() => {
spyOn(component, 'getResults').and.returnValue(Promise.resolve('bar'));
component.ngOnInit();
fixture.whenStable().then(() => {
// Everything in here gets skipped when I run the test
fixture.detectChanges();
// This should cause the test to fail, but it doesn't because it not run in time
expect(true).toBe(false)
});
}));
// my.component.spec.ts (Jasmine version that works)
it('should load results', (done) => {
spyOn(component, 'getResults').and.returnValue(Promise.resolve('bar'));
component.ngOnInit();
fixture.whenStable().then(() => {
fixture.detectChanges();
// This should fail and it does because the test works using Jasmine "done" callback
expect(true).toBe(false);
done();
});
});
source to share
Thanks to @yurzui Plunker, I figured my problem was caused by my call fixture.detectChanges()
in my method beforeEach()
:
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
});
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
// The following line is to blame! Removing it makes the test work correctly.
fixture.detectChanges();
});
source to share
I had some problems with this, we solved it with angular / testing async function in beforeEach:
beforeEach(async(() => { // <-- use async
TestBed.configureTestingModule({
declarations: [AppComponent],
});
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
// The following line is to blame! Removing it makes the test work correctly.
fixture.detectChanges();
}));
... as the documentation says: https://angular.io/guide/testing#async-test-with-async .
source to share