Timeout exceeded for Mocha promises

531 Views Asked by At

I have a async function that awaits a promise which resolves when it receives some 'data'. However, when I run the test, I get a Error: Timeout of 300000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

Here is my code snippet, I am using this in truffle to test solidity contracts :

contract("Test", async (accounts) => {
  it("test description", async () => {
       
      let first = await getFirstEvent(oracle.LogResult({fromBlock:'latest'}));
      let second = await getFirstEvent(oracle.LogResult({fromBlock:'latest'}));
      Promise.all([first,second]);
      //some assertion code
      
  });
  
  const getFirstEvent = (_event) => {
    return new Promise((resolve, reject) => {
      _event.once('data', resolve).once('error', reject)
    });
  }

});

Isn't the promise resolving ? I can see 'data' coming back in the callback because I am emitting the callback event in the solidity code I am testing.

2

There are 2 best solutions below

0
On

I managed to resolve this issue, so posting it here so that others can use the approach.

I created a Promise that times out after a duration we can set :

const timeoutPromise = new Promise((_, reject) => {
  setTimeout(() => {a
    reject(new Error('Request timed out'));
  }, 200000);
})

Then, I race the timeoutPromise with the Promise which is fetching data, like this for the case I posted :

Promise.race([getFirstEvent(oracle.LogResult({fromBlock:'latest'})), timeoutPromise]);
0
On

It looks to me like there's a few things wrong here.

First of all, your function isn't returning anything i.e. it should be return Promise.all([first, second]);.

Secondly, if the goal of the promise.all is to execute the promises in parallel, then that's not what it's doing here because you already have await statements on those function calls above. What you are looking for here would be:

return await Promise.all([
  getFirstEvent(oracle.LogResult({fromBlock:'latest'}),
  getFirstEvent(oracle.LogResult({fromBlock:'latest'})]);

Now in terms of the promise not resolving, I'm assuming the event is generated from oracle.LogResult(). In this case, what you'd want to do is setup your promises to listen for the event first, for example:

let first = getFirstEvent();
let second = getSecondEvent();

Now you have 2 promises that are listening for the events. Next, you generate the event:

oracle.LogResult({ fromBlock: 'latest' });
oracle.LogResult({ fromBlock: 'latest' });

Finally, you ensure you wait on the result of the promises:

return await Promise.all([first, second]);