Node.js 使用 Mocha、sinon 和 chai 进行 axios 单元测试
Node.js axios unit testing using Mocha, sinon and chai
我有 node.js 组件名称 controller.js,它有一个函数调用 api 服务,使用带选项的 axios,它还有用于错误处理的 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 函数和 catch 函数进行存根以进行错误处理。
因此无法覆盖纽约市的 axios success 和 catch 函数的代码。
请帮忙..
首先,你不能使用try...catch
语句来捕获异步代码,如果你想这样做,你需要使用async/await
等待承诺被解决或拒绝。此外,由于您已经捕获了 axios
异常并且没有重新抛出它,因此您不需要 try...catch
.
其次,您正在尝试存根 axios
函数,它是从 axios
模块导入的独立函数。 Sinon 不支持。您需要使用 Link Seams, so we will be using 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
---------------|---------|----------|---------|---------|-------------------
我有 node.js 组件名称 controller.js,它有一个函数调用 api 服务,使用带选项的 axios,它还有用于错误处理的 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 函数和 catch 函数进行存根以进行错误处理。 因此无法覆盖纽约市的 axios success 和 catch 函数的代码。 请帮忙..
首先,你不能使用try...catch
语句来捕获异步代码,如果你想这样做,你需要使用async/await
等待承诺被解决或拒绝。此外,由于您已经捕获了 axios
异常并且没有重新抛出它,因此您不需要 try...catch
.
其次,您正在尝试存根 axios
函数,它是从 axios
模块导入的独立函数。 Sinon 不支持。您需要使用 Link Seams, so we will be using 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
---------------|---------|----------|---------|---------|-------------------