Javascript 断言该方法已在与摩卡和西农的承诺中被调用

Javascript 断言该方法已在与摩卡和西农的承诺中被调用,javascript,unit-testing,promise,mocha.js,sinon,Javascript,Unit Testing,Promise,Mocha.js,Sinon,我有以下简化的方法和测试,我想测试HandlerResponse()是否被调用 测试失败,根本没有调用HandlerResponse()。如果我修改代码以在承诺之外运行HandlerResponse,测试将成功完成 这是因为承诺是异步的,并且断言是在承诺之前运行的吗?如果是这样的话,在运行断言之前,我如何等待对断言的承诺完成 代码: 测试: 您忘记了将async/await添加到单元测试中,并更改为返回服务.getList(…)。否则,断言将在解析service.getList(…)的承诺之前执

我有以下简化的方法和测试,我想测试HandlerResponse()是否被调用

测试失败,根本没有调用HandlerResponse()。如果我修改代码以在承诺之外运行HandlerResponse,测试将成功完成

这是因为承诺是异步的,并且断言是在承诺之前运行的吗?如果是这样的话,在运行断言之前,我如何等待对断言的承诺完成

代码:

测试:


您忘记了将
async/await
添加到单元测试中,并更改为
返回服务.getList(…)
。否则,断言将在解析
service.getList(…)
的承诺之前执行

listActions.ts

从“/service”导入*作为服务;
从“/appActions”导入{HandlerResponse,addNotification};
导出函数获取列表(id){
返回调度=>{
return service.getList(id)。然后(
响应=>{
HandlerResponse(响应);
},
错误=>{
添加通知(错误);
}
);
};
}
appActions.ts

导出函数handleResponse(res){
控制台日志(“HandlerResponse”);
}
导出函数addNotification(错误){
console.log(“addNotification”);
}
service.ts

导出函数getList(id){
返回新承诺(解决=>{
设置超时(()=>{
决心([]);
}, 5000);
});
}
listActions.spec.ts

从“/service”导入*作为服务;
将*作为appActions从“/appActions”导入;
从“/listActions”导入*作为listActions;
从“sinon”进口sinon;
描述(“获取列表”,()=>{
让我们来看看存根;
让HandlerResponseSub;
在每个之前(()=>{
getListStub=sinon.stub(服务,“getList”);
HandlerResponseSub=sinon.stub(appActions,“HandlerResponse”);
});
之后(()=>{
getListStub.restore();
HandlerResponseSub.restore();
});
它(“成功时应发送HandlerResponse”,异步()=>{
const dispatchStub=sinon.stub();
常数id=1;
const returnValue=“返回值”;
getListStub.withArgs(id).resolves(returnValue);
wait listActions.fetchList(id)(dispatchStub);
sinon.assert.calledOnce(getListStub);
sinon.assert.notCalled(dispatchStub);
sinon.assert.calledOnce(HandlerResponseSub);//失败
});
});
单元测试结果和覆盖率报告:

fetchList
✓ 成功后是否应派遣专人负责
1次通过(95毫秒)
---------------------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
---------------------|----------|----------|----------|----------|-------------------|
所有文件| 83.33 | 100 | 53.85 | 82.86 ||
appActions.ts | 50 | 100 | 0 | 50 | 2,6|
listActions.spec.ts | 100 | 100 | 100 | 100 ||
listActions.ts | 85.71 | 100 | 75 | 85.71 | 11|
service.ts | 25 | 100 | 0 | 25 | 2,3,4|
---------------------|----------|----------|----------|----------|-------------------|

源代码:

您忘记了将
异步/await
添加到单元测试中,并更改为
返回服务.getList(…)
。否则,断言将在解析
service.getList(…)
的承诺之前执行

listActions.ts

从“/service”导入*作为服务;
从“/appActions”导入{HandlerResponse,addNotification};
导出函数获取列表(id){
返回调度=>{
return service.getList(id)。然后(
响应=>{
HandlerResponse(响应);
},
错误=>{
添加通知(错误);
}
);
};
}
appActions.ts

导出函数handleResponse(res){
控制台日志(“HandlerResponse”);
}
导出函数addNotification(错误){
console.log(“addNotification”);
}
service.ts

导出函数getList(id){
返回新承诺(解决=>{
设置超时(()=>{
决心([]);
}, 5000);
});
}
listActions.spec.ts

从“/service”导入*作为服务;
将*作为appActions从“/appActions”导入;
从“/listActions”导入*作为listActions;
从“sinon”进口sinon;
描述(“获取列表”,()=>{
让我们来看看存根;
让HandlerResponseSub;
在每个之前(()=>{
getListStub=sinon.stub(服务,“getList”);
HandlerResponseSub=sinon.stub(appActions,“HandlerResponse”);
});
之后(()=>{
getListStub.restore();
HandlerResponseSub.restore();
});
它(“成功时应发送HandlerResponse”,异步()=>{
const dispatchStub=sinon.stub();
常数id=1;
const returnValue=“返回值”;
getListStub.withArgs(id).resolves(returnValue);
wait listActions.fetchList(id)(dispatchStub);
sinon.assert.calledOnce(getListStub);
sinon.assert.notCalled(dispatchStub);
sinon.assert.calledOnce(HandlerResponseSub);//失败
});
});
单元测试结果和覆盖率报告:

fetchList
✓ 成功后是否应派遣专人负责
1次通过(95毫秒)
---------------------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
---------------------|----------|----------|----------|----------|-------------------|
所有文件| 83.33 | 100 | 53.85 | 82.86 ||
appActions.ts | 50 | 100 | 0 | 50 | 2,6|
listActions.spec.ts | 100 | 100 | 100 | 100 ||
listActions.ts
export function fetchList(id) {
  // handleResponse(response); // Works here

  return (dispatch) => {
    service.getList(id).then((response) => {
      handleResponse(response); // Doesnt work here
    }, (error) => {
      addNotification(error);
    });
  };
}
describe('fetchList', () => {
  let getListStub;
  let handleResponseStub;

  beforeEach(() => {
    getListStub = sinon.stub(service, 'getList');
    handleResponseStub = sinon.stub(appActions, 'handleResponse');
  });

  afterEach(() => {
    getListStub.restore();
    handleResponseStub.restore();
  });

  it('should dispatch handleResponse on success', () => {
    const dispatchStub = sinon.stub();
    const id = 1;
    const returnValue = 'return value';
    getListStub.withArgs(id).resolves(returnValue);

    listActions.fetchList(id)(dispatchStub);

    sinon.assert.calledOnce(getListStub);
    sinon.assert.calledOnce(handleResponseStub); // Fails
  });
});