Javascript 单元测试具有回调函数的函数(请求模块)

Javascript 单元测试具有回调函数的函数(请求模块),javascript,unit-testing,mocking,mocha.js,sinon,Javascript,Unit Testing,Mocking,Mocha.js,Sinon,我正在我的NodeJS项目中进行测试,我想对以下功能进行单元测试: function myRequest(targetUrl, reqBody) { return new Promise((resolve, reject) => { request.post(targetUrl, { json: reqBody }, (error, response, body) => { if (!error && response.statusCode =

我正在我的NodeJS项目中进行测试,我想对以下功能进行单元测试:

function myRequest(targetUrl, reqBody) {
  return new Promise((resolve, reject) => {
    request.post(targetUrl, { json: reqBody }, (error, response, body) => {
      if (!error && response.statusCode === 200) {
        resolve(body.transferId);
      } else {
        reject(error || body.description || body);
      }
    });
  });
}
我用的是摩卡咖啡和西农咖啡。如何测试此函数


首先,我使用自己的模拟请求模块测试了成功场景。现在,我想做一个错误场景,可能是post函数出错。我如何在不更改或创建新的模拟请求(返回错误)的情况下执行此操作?是否可能?

这是单元测试解决方案,您应该使用
sinon.stub

例如。
index.ts

从“请求”导入请求;
导出函数myRequest(targetUrl、reqBody){
返回新承诺((解决、拒绝)=>{
post(targetUrl,{json:reqBody},(错误,响应,body)=>{
如果(!error&&response.statusCode==200){
决议(主体.转让ID);
}否则{
拒绝(错误| | body.description | | body);
}
});
});
}
索引规范ts

从“.”导入{myRequest};
从‘柴’进口柴;
从“sinon”进口sinon;
承诺从“承诺的柴胡”进口柴胡;
从“请求”导入请求;
柴。使用(柴);
const{expect}=chai;
描述('myRequest',()=>{
它('should request success',async done=>{
//@ts忽略
const stub=sinon.stub(请求,'post').callsFake((uri,选项,回调)=>{
const mResponse={statusCode:200};
const mBody={transferId:1};
回调(null、mResponse、mBody);
完成();
});
const actualValue=wait myRequest('url',{});
//@ts忽略
calledOnceWith('url',{json:{}});
expect(实际值)至等式(1);
stub.restore();
});
它('should throw error use request error',async done=>{
const mError=新错误(“内部服务器错误”);
const mResponse={statusCode:500};
//@ts忽略
const stub=sinon.stub(请求,'post').callsFake((uri,选项,回调)=>{
回调(mError、mResponse、null);
完成();
});
wait expect(myRequest('url',{})).to.be.rejectedWith(mError);
//@ts忽略
calledOnceWith('url',{json:{}});
stub.restore();
});
它('应该抛出错误并使用body.description作为错误消息',异步完成=>{
const mResponse={statusCode:500};
const mBody={description:'some error'};
//@ts忽略
const stub=sinon.stub(请求,'post').callsFake((uri,选项,回调)=>{
回调(null、mResponse、mBody);
完成();
});
wait expect(myRequest('url',{})).to.be.rejectedWith(mBody.description);
//@ts忽略
calledOnceWith('url',{json:{}});
stub.restore();
});
它('should throw error use body as error message',async done=>{
const mResponse={statusCode:500};
const mBody=‘某些错误’;
//@ts忽略
const stub=sinon.stub(请求,'post').callsFake((uri,选项,回调)=>{
回调(null、mResponse、mBody);
完成();
});
wait expect(myRequest('url',{})).to.be.rejectedWith(mBody);
//@ts忽略
calledOnceWith('url',{json:{}});
stub.restore();
});
});
100%覆盖率的单元测试结果:

myRequest
✓ 应该要求成功
✓ 应该抛出错误使用请求错误
✓ 应抛出错误并将body.description用作错误消息
✓ 应该抛出错误并将正文用作错误消息
4次通过(13毫秒)
---------------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
---------------|----------|----------|----------|----------|-------------------|
所有文件| 100 | 100 | 100 | 100 ||
索引规范ts | 100 | 100 | 100 | 100 ||
index.ts | 100 | 100 | 100 | 100 ||
---------------|----------|----------|----------|----------|-------------------|

源代码:

成功了,非常感谢。因为我不想使用任何外部库,所以我只需要为请求库创建一个mock,并用proxyquire进行替换。