Test an Async function in JS - Error: "Did you forget to use await"
In the code above await
is called on the result of calling getStatus
on the result of calling ContainerGlobals.getResponseFromURL()
.
ContainerGlobals.getResponseFromURL()
returns a Promise
and immediately calling getStatus()
on the Promise
gives an error since getStatus
"does not exist on Promise
".
await
needs to be called on the Promise
returned by ContainerGlobals.getResponseFromURL()
, and getStatus
should be called on the result returned by await
.
The quickest way to fix this is to throw parenthesis around the await
:
test('Async function', async () => {
expect.assertions(1);
const data = (await ContainerGlobals.getResponseFromURL()).getStatus();
expect(data).toBe(207); // SUCCESS
});
...but you might want to split the await
line into two lines for readability:
test('Async function', async () => {
expect.assertions(1);
const result = await ContainerGlobals.getResponseFromURL(); // let the Promise resolve
const data = result.getStatus(); // call getStatus on the result
expect(data).toBe(207); // SUCCESS
});
lanzchilz
Updated on January 11, 2020Comments
-
lanzchilz over 4 years
My code looks like this:
public getUrl(url) { //returns URL ... } public getResponseFromURL(): container { let myStatus = 4; const abc = http.get(url, (respon) => const { statusCode } = respon; myStatus = statusCode; console.log('Inside callback' +myStatus); .on('error', (err) => { console.log('Things have gone wrong' + err); }); console.log('ITS COMPLICATED' +myStatus); return new Container(status, body, header); } }
The problem I am facing is because of the asynchronous nature of JS and the console.log('ITS COMPLICATED') gets executed before the one in the callback function. I am trying to have the first one executed before the last console.log!
I am using Async/Await like below:
public timeoutPromise(time: any) { return new Promise((resolve) => { setTimeout(() => { resolve(Date.now()); }, time); }); } public doSomethingAsync() { return this.timeoutPromise(1000); }
As a result changed my getResponseFromURL() to:
public async getResponseFromURL(): Promise<container> { this.myStatus = 7; console.log(0); await this.doSomethingAsync(); console.log(1); const abc = http.get(url, (respon) => { const { statusCode } = respon; this.myStatus = statusCode; console.log('Inside Callback ' + statusCode); }).on('error', (err) => { console.log('Things have gone wrong ' + err); }); await this.doSomethingAsync(); console.log(2); await this.doSomethingAsync(); console.log('Is it simple lalala ' + this.myStatus); await this.doSomethingAsync(); } }
The problem with doing this was if my container class (return type of getResponseFromURL()) is a container for status and body when I am testing this async function, before
expect.getResponseFromURL().getStatus().toBe(200)
would work.Test looks like below:
test('Async function', async () => { expect.assertions(1); const data = await ContainerGlobals.getResponseFromURL().getStatus(); expect(data).toBe(207); });
Now I am getting error from
.getStatus()
and I am not sure how to bypass this error?"does not exist on Promise"