使用 Mocha、sinon 和 chai 进行 Node.js axios 单元测试

如何解决使用 Mocha、sinon 和 chai 进行 Node.js axios 单元测试

我有 node.js 组件名称 controller.js,它有一个使用 axios 和选项调用 api 服务的函数,它还具有用于错误处理的 catch 函数。我无法存根 axios 函数以便通过单元测试来覆盖它。

下面是 controller.js 组件。

const axios = require('axios');
export.getData = function(req,res,next) {
  try {
     const options = {
            method: 'GET',headers: headers,url,params: queryParams
     };  
     axios(options).then(function (response) {
            res.json(response.data);
        })
            .catch(function (error) {
                if (error && error.response) {
                    if (error.response.status === 401) {
                        res.status(500).send({ error: true,message: 'There seems to be an issue,please try after sometime' });                   
                    }
                 }
             });
  }
}

下面是我的 controller.test.js

const chai = require('chai');
const assert = chai.assert;
const axios = require('axios');
const sinon = require('sinon');
const controller = require('../controllersr');

describe("controller API testing",() => {

it("should call getMarketId function and return status 200 on success",function (done) {
        const req = { };
        const res =  { json: {greet: "hello"},status: 200};
        var mockStub = sinon.stub(axios,'get').resolves(res);
        controller.getData(req,res);
        assert.equal(res.status,200);
        mockStub.restore();
        done();
    });

});

在这里,我无法存根 axios 函数和捕获函数以进行错误处理。 因此无法覆盖纽约市 axios 成功和捕获功能代码。 请帮忙..

解决方法

首先,您不能使用try...catch 语句来捕获异步代码,如果您想这样做,您需要使用async/await 来等待promise 被解析或拒绝。此外,由于您已经捕获了 axios 异常并且没有重新抛出它,因此您不需要 try...catch

其次,您试图存根 axios 函数,它是从 axios 模块导入的独立函数。诗浓不支持。您需要使用 Link Seams,因此我们将使用 proxyquire 来构建接缝。

例如

controller.js

const axios = require('axios');

exports.getData = function (req,res,next) {
  const options = {
    method: 'GET',headers: headers,url,params: queryParams,};
  axios(options)
    .then(function (response) {
      res.json(response.data);
    })
    .catch(function (error) {
      if (error && error.response) {
        if (error.response.status === 401) {
          res.status(500).send({ error: true,message: 'There seems to be an issue,please try after sometime' });
        }
      }
    });
};

controller.test.js

const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('controller API testing',() => {
  it('should call getMarketId function and return status 200 on success',async () => {
    const req = {};
    const res = { json: sinon.stub(),status: 200 };
    const axiosStub = sinon.stub().resolves({ data: { greet: 'hello' } });
    const controller = proxyquire('./controller',{
      axios: axiosStub,});
    await controller.getData(req,res);
    sinon.assert.calledWithExactly(axiosStub,{
      method: 'GET',headers: {},url: 'http://localhost:3000/api',params: {},});
    sinon.assert.calledWithExactly(res.json,{ greet: 'hello' });
  });
});

单元测试结果:

  controller API testing
    ✓ should call getMarketId function and return status 200 on success (1306ms)


  1 passing (1s)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |    62.5 |        0 |   66.67 |    62.5 |                   
 controller.js |    62.5 |        0 |   66.67 |    62.5 | 15-17             
---------------|---------|----------|---------|---------|-------------------

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?