我正在进行摩卡单元测试。在那里,我用req,res,next来调用api。然后它在那个方法内部调用另一个api是一个cloud api。得到一个记录。返回记录。云API在这里称为真正的api。我需要存根那个api。在这里粘贴代码。请给我一个建议。 我正在使用sinon stub。
controller.js
module.exports.getAllRooms = (req, res) => {
// console.log('test mock called ----> > > > ');
var selector = req.params.selector;
options.method = 'GET';
options.url = lifxApiProps.baseUrl + selector;
options.body = {};
// console.log('options ---> ', options);
http.get(options, (error, response, body) => {
if (error) return Error(error);
findDups = _.map(body, 'group');
return res.send(_.uniqBy(findDups, 'name'));
});
};
test.js:
describe('#getAllRooms', () => {
beforeEach(() => {
req.params = { selector: 'all' };
req.body = {};
});
it('should call lifx api ', (done) => {
const callbackRes = [
{
id: 'd073d5127219',
uuid: '024008b0-af2d-4170-827d-b0288088c5c3',
label: 'LIFX Bulb 127219',
connected: true,
power: 'on',
color: {
hue: 240,
saturation: 1,
kelvin: 3500,
},
brightness: 0.998794537270161,
group: {
id: '36b47494e70bb82e44e6a7804f5c6300',
name: 'Jaime Office',
},
location: {
id: '6f2971162984b79fe437dd5f1f73579e',
name: 'Knocki HQ',
},
product: {
name: 'Color 1000 BR30',
identifier: 'lifx_color_br30',
company: 'LIFX',
capabilities: {
has_color: true,
has_variable_color_temp: true,
has_ir: false,
has_multizone: false,
},
},
last_seen: '2017-08-03T06:04:41Z',
seconds_since_seen: 0,
},
];
sandbox.stub(http, 'get', (options, callback) => callback(null, null, callbackRes));
res.send = (result) => {
console.info('response of get all rooms ----> ', result);
expect(result).to.exist;
done();
};
controller.getAllRooms(req, res, next);
});
});
存根在这里不起作用:错误
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
答案 0 :(得分:0)
这是单元测试解决方案:
controller.js
:
const _ = require("lodash");
const http = require("http");
const lifxApiProps = { baseUrl: "http://google.com" };
module.exports.getAllRooms = (req, res) => {
const options = {};
var selector = req.params.selector;
options.method = "GET";
options.url = lifxApiProps.baseUrl + selector;
options.body = {};
http.get(options, (error, response, body) => {
if (error) return Error(error);
findDups = _.map(body, "group");
return res.send(_.uniqBy(findDups, "name"));
});
};
controller.test.js
:
const { getAllRooms } = require("./controller");
const http = require("http");
const sinon = require("sinon");
describe("getAllRooms", () => {
afterEach(() => {
sinon.restore();
});
it("should send response", () => {
const getStub = sinon.stub(http, "get");
const sendStub = sinon.stub();
const mReq = { params: { selector: "/a" } };
const mRes = { send: sendStub };
getAllRooms(mReq, mRes);
const mBody = [{ group: "google" }, { group: "reddit" }];
getStub.yield(null, {}, mBody);
sinon.assert.calledWith(
getStub,
{
method: "GET",
url: "http://google.com/a",
body: {}
},
sinon.match.func
);
sinon.assert.calledWith(sendStub, ["google"]);
});
it("should handle error", () => {
const getStub = sinon.stub(http, "get");
const sendStub = sinon.stub();
const mReq = { params: { selector: "/a" } };
const mRes = { send: sendStub };
getAllRooms(mReq, mRes);
const mError = new Error("network error");
getStub.yield(mError, {}, null);
sinon.assert.calledWith(
getStub,
{
method: "GET",
url: "http://google.com/a",
body: {}
},
sinon.match.func
);
sinon.assert.notCalled(sendStub);
});
});
覆盖率100%的单元测试结果:
getAllRooms
✓ should send response
✓ should handle error
2 passing (15ms)
--------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
controller.js | 100 | 100 | 100 | 100 | |
controller.test.js | 100 | 100 | 100 | 100 | |
--------------------|----------|----------|----------|----------|-------------------|
源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/45481923