I have a service in Angular that runs a function in order to fetch data from some internal API endpoints. The structure of this function is as follows (with console logs for clarity on execution order):
async initializeAPI() {
let data = await fetch('//my 1st api call');
data.json().then(r => {
console.log("then1");
this.CLASSDATA = r.res.rows;
});
console.log("API read_classdata called");
data = await fetch('//my 2nd api call');
data.json().then(r => {
console.log("then2");
this.RABILITYDATA = r.res.rows;
});
data = await fetch('//my 3rd api call');
data.json().then(r => {
this.PABILITYDATA = r.res.rows;
console.log("then3", r.res.rows[0], this.PABILITYDATA[0]);
});
console.log("API read_abilitydata called");
}
I am now trying to test this function in my spec.ts file, to confirm that all the data is fetched and parsed properly. However, I have not found an approach that allows all of these .then blocks to finish before starting in on expect statements.
In my spec, I set up some mockdata and pass those to a fetch spy to handle the fetches. As far as I can tell, that part is working fine. My spec.ts looks as follows:
setup and beforeEach-
let service: PartyService;
let initspy: jasmine.Spy;
//also the mockdata is set up here, left out for legibility
beforeEach(() => {
//this prevents initializeAPI in constructor from running and making real fetch calls
initspy = spyOn(PartyService.prototype, "initializeAPI");
TestBed.configureTestingModule({});
service = TestBed.inject(PartyService);
}
test case-
it('should initialize apis for class and ability', async() => {
service.CLASSDATA = [];
const fetchspy = spyOn(window, 'fetch').and.returnValues(Promise.resolve(classres), Promise.resolve(rabres), Promise.resolve(pabres) ); //returning mockdata for all 3 fetches using spy
initspy = initspy.and.callThrough();
await service.initializeAPI();
expect(fetchspy).toHaveBeenCalledTimes(3); //this passes
expect(service.CLASSDATA).toEqual(MOCKCLASSDATA); //this is failing
});
However, my console prints the logs in the following order:
API read_classdata called
API read_abilitydata called
spec checkpoint
[TEST FAILS HERE]
then1 through then3 here, with data assigned correctly
Based on these console logs, it seems to me that the test case successfully waits for the fake fetch() requests to finish, but does NOT wait for the .then blocks that process the fetched data.
I've tried a few variants, including using fakeAsync() with tick(), waitForAsync, and making a spy for Response.then(), but either I've missed a trick while implementing these approaches or else they don't fix the underlying issue.
Could this be a problem with the implementation of my original service function that I need to change? Is there a way to rewrite the test case such that it does wait for the .then blocks? Thank you in advance for your time!