在执行其他任何操作之前,先测试一个函数是否正在等待

时间:2018-07-17 06:49:24

标签: javascript unit-testing asynchronous promise async-await

假设我有一个函数,它执行异步操作(doStuffAsync()),然后打算做一些其他事情(doOtherStuff())。

doStuffAsync()返回一个Promise

还假设一切都是可模拟的。

如何在尝试doStuffAsync()之前测试我的函数是否等待doOtherStuff()

我曾想过使用doStuffAsync()模拟resolve => setTimeout(resolve(), timeout),但是基于超时的测试却非常脆弱。

2 个答案:

答案 0 :(得分:0)

您需要一个doStuffAsyncdoOtherStuff都可以访问的标志。

doStuffAsync()中写入该标志
doOtherStuff()中,从该标志中读取并确定它是否被写入

类似的东西:

var isAsyncRunning = false;
    
function doStuffAsync(){
  isAsyncRunning = true;
  new Promise(function(resolve, reject) {
    setTimeout(()=>{
      isAsyncRunning = false;
      resolve(); //irrelevant in this exercise 
    }, 1000);
  });
      
}
doStuffAsync(); 
function doOtherStuff(){
  if(isAsyncRunning){
    console.log("Async is running.");
  } else {
    console.log("Async is no longer running.");
  };

}
doOtherStuff();
setTimeout(() => {
  //calling doOtherStuff 2 seconds later..
  doOtherStuff();
}, 2000);

答案 1 :(得分:0)

我设法用比%matplotlib inline import matplotlib.pyplot as plt import pandas as pd import numpy as np import os from scipy import interpolate #Original Data pwl_data = np.array([[0,1e3, 1e5, 1e8], [-90,-90, -90, -130]]) #spine interpolation pwl_spline = interpolate.splrep(pwl_data[0], pwl_data[1]) spline_x = np.linspace (0,1e8, 10000) legend = [] plt.plot(pwl_data[0],pwl_data[1]) plt.plot(spline_x,interpolate.splev(spline_x,pwl_spline ),'*') legend.append("Data") legend.append("Interpolated Data") plt.xscale('log') plt.legend(legend) plt.grid(True) plt.grid(b=True, which='minor', linestyle='--') plt.show() setTimeout丑陋的解决方案来完成它。

setImmediate

function testedFunction() { await MyModule.doStuffAsync(); MyModule.doOtherStuff(); } it('awaits the asynchronous stuff before doing anything else', () => { // Mock doStuffAsync() so that the promise is resolved at the end // of the event loop – which means, after the test. // - const doStuffAsyncMock = jest.fn(); const delayedPromise = new Promise<void>(resolve => setImmediate(resolve())); doStuffAsyncMock.mockImplementation(() => delayedPromise); const doOtherStuffMock = jest.fn(); MyModule.doStuffAsync = doStuffAsyncMock; MyModule.doOtherStuffMock = doOtherStuffMock; testedFunction(); expect(doOtherStuffMock).toHaveBeenCalledTimes(0); } 会将承诺的解决推迟到事件循环结束时,即测试完成后。

因此,您断言setImmediate没有被调用:

  • 如果doOtherStuff()内有await,就会通过
  • 如果没有,将失败。