Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 单元测试嵌套异步函数时异步回调超时_Javascript_Unit Testing_Jestjs - Fatal编程技术网

Javascript 单元测试嵌套异步函数时异步回调超时

Javascript 单元测试嵌套异步函数时异步回调超时,javascript,unit-testing,jestjs,Javascript,Unit Testing,Jestjs,我想实现一个函数,它异步命中一些API并进行一些计算。然而,我希望使用承诺(也是因为我认为为它们编写单元测试很容易) 这是我想写的函数 const CalcFactory = (someApi1, someApi2, someApi3) => async function calculation(params){ return new Promise((res, rej) =>{ const data1 = someApi1.getData() // getData

我想实现一个函数,它异步命中一些API并进行一些计算。然而,我希望使用承诺(也是因为我认为为它们编写单元测试很容易)

这是我想写的函数

const CalcFactory = (someApi1, someApi2, someApi3) => 
 async function calculation(params){
  return new Promise((res, rej) =>{
    const data1 = someApi1.getData() // getData is async
    someApi2.getData((err, data) =>{
       if(err)
         rej(err);
       else
         res();
      });
    });
 }
现在的问题是如何测试和模拟这一点?我的第一个测试是是否调用了所有的api方法,但我已经很难做到这一点

const Calculator = CalcFactory(api1Mock, api2Mock, api3Mock);

if('should hit all external apis', () => {
return Calculator(somedada).then(()=>{
   expect(api1Mock.getData).toHaveBeenCalledWith(someData);
   expect(api2Mock.getData).toHaveBeenCalledWith(somedata);
   });

});
模拟结果如下所示:

const api1Mock = {
   someData: jest.fn(),
}

const api2Mock = {
someData: jest.fn().mockResolvedValue({
      data:{},
   })
}

然而,当我运行测试时,我总是得到一个超时。我也不确定这是否是一种编写函数的好方法,但我真的希望使用承诺。

一个地方有
getData
,另一个地方有
someData
。考虑到承诺没有被拒绝,这不是问题
Calculator(somedada)
promise未解析,因为
someApi2.getData
被错误地模拟并导致挂起的promise

async
函数返回承诺而不使用
wait
是一种反模式。这意味着要么它不能从异步中获益,要么承诺构造函数除了对非承诺API的承诺之外,还包含了太多的内容

如果使用
async
是合理的,则可以:

async function calculation(params){
  ...
  const data1 = someApi1.getData()
  const data2 = await new Promise((res, rej) =>{
      someApi2.getData((err, data) => {
       if(err)
         rej(err);
       else
         res();
      });
  });
  ...
}
在节点中,可以使用
util.promisify
提示错误优先回调

和mocked
someApi2.getData
应该像预期的那样使用回调:

const api2Mock = {
  getData: jest.fn().mockImplementation(cb => cb(null, 'data'))
}

如果
someApi2.getData
被多次使用,那么有必要承诺它,而不是每次都使用promise构造函数。

谢谢,我承诺了
someApi2.getData
,只需等待效果良好的承诺。