由于某种原因,我在使用类似的设置正确运行这个简单的测试时遇到了一些麻烦,我之前曾多次使用过。
也许一双新鲜的眼睛可以帮助我理解为什么我的方法generateReport
没有被调用而我的stubs
没有被预期的参数触发?
BYE
和GOOD
并且测试返回错误:AssertError: expected stub to be called with arguments
我的索引文件:
const errorHandler = require('./lib/handlers/error-handler')
const transformRequest = require('./lib/handlers/request-converter')
const convert = require('./lib/convert')
exports.generateReport = function generateReport(req, res) {
console.log('HELLO')
const objectToPopulateTemplate = transformRequest(req.body)
convert(objectToPopulateTemplate, function (e, data) {
if (e) {
console.log('BYE')
const error = errorHandler(e)
return res.send(error.httpCode).json(error)
}
console.log('GOOD')
res
.set('Content-Type', 'application/pdf')
.set('Content-Disposition', `attachment; filename=velocity_report_${new Date()}.pdf`)
.set('Content-Length', data.length)
.status(200)
.end(data)
})
}
我的测试文件:
const proxyquire = require('proxyquire')
const assert = require('assert')
const sinon = require('sinon')
const fakeData = require('./data/sample-request.json')
describe('report-exporter', () => {
describe('generateReport', () => {
const fakeError = new Error('Undefined is not a function')
let res, resSendStub, resStatusStub, resEndStub, resSetStub, resJsonStub, req, convertStub, generate
before(() => {
resSendStub = sinon.stub()
resJsonStub = sinon.stub()
resStatusStub = sinon.stub()
resEndStub = sinon.stub()
resSetStub = sinon.stub()
convertStub = sinon.stub()
res = {
send: function(errorCode) {
return resSendStub(errorCode)
},
json: function(object) {
return resJsonStub(object)
},
set: function(arg1, arg2) {
return resSetStub(arg1, arg2)
},
status: function(code) {
return resStatusStub(code)
},
end: function(data) {
return resEndStub(data)
}
}
req = {
body: {}
}
generate = proxyquire('./../index', {
'./lib/convert': function() {
return convertStub
}
})
})
it('Should return an error response', () => {
convertStub.throws(fakeError)
generate.generateReport(req, res)
sinon.assert.calledWith(resSendStub, '500')
})
})
})
答案 0 :(得分:0)
看起来您proxyquire
错误地./lib/convert
了convert
。使用objectToPopulateTemplate
和回调function (e, data)
调用原始convert
。这就是负责错误处理和发送响应的回调。
存根convertStub
函数根本不关心提供的回调,因此回调永远不会被调用。
您最想要的是将参数传递给'./lib/convert': function(objectToPopulateTemplate, cb) {
return convertStub(objectToPopulateTemplate, cb);
}
并稍后处理它们:
it('Should return an error response', () => {
generate.generateReport(req, res);
const cb = convertStub.getCall(0).args[1];
// simulate `convert` to fail
cb(fakeError);
sinon.assert.calledWith(resSendStub, '500')
})
然后
UIDatePicker
答案 1 :(得分:0)
这是单元测试解决方案:
index.js
:
const errorHandler = require("./error-handler");
const transformRequest = require("./request-converter");
const convert = require("./convert");
exports.generateReport = function generateReport(req, res) {
console.log("HELLO");
const objectToPopulateTemplate = transformRequest(req.body);
convert(objectToPopulateTemplate, function(e, data) {
if (e) {
console.log("BYE");
const error = errorHandler(e);
return res.send(error.httpCode).json(error);
}
console.log("GOOD");
res
.set("Content-Type", "application/pdf")
.set(
"Content-Disposition",
`attachment; filename=velocity_report_${new Date()}.pdf`
)
.set("Content-Length", data.length)
.status(200)
.end(data);
});
};
error-handler.js
:
module.exports = function(error) {
return error;
};
request-converter.js
:
module.exports = function transformRequest(body) {
return body;
};
convert.js
:
module.exports = function convert(body, callback) {
callback();
};
index.spec.js
:
const sinon = require("sinon");
const proxyquire = require("proxyquire");
describe("report-exporter", () => {
describe("generateReport", () => {
afterEach(() => {
sinon.restore();
});
const fakeError = new Error("Undefined is not a function");
fakeError.httpCode = 500;
it("Should return an error response", () => {
const logSpy = sinon.spy(console, "log");
const mReq = { body: {} };
const mRes = { send: sinon.stub().returnsThis(), json: sinon.stub() };
const convertStub = sinon.stub();
const errorHandlerStub = sinon.stub().returns(fakeError);
const transformRequestStub = sinon.stub().returns(mReq.body);
const generate = proxyquire("./", {
"./convert": convertStub,
"./error-handler": errorHandlerStub,
"./request-converter": transformRequestStub
});
generate.generateReport(mReq, mRes);
convertStub.yield(fakeError, null);
sinon.assert.calledWith(transformRequestStub);
sinon.assert.calledWith(convertStub, {}, sinon.match.func);
sinon.assert.calledWith(errorHandlerStub, fakeError);
sinon.assert.calledWith(logSpy.firstCall, "HELLO");
sinon.assert.calledWith(logSpy.secondCall, "BYE");
});
});
});
带有覆盖率报告的单元测试结果:
report-exporter
generateReport
HELLO
BYE
✓ Should return an error response (94ms)
1 passing (98ms)
----------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------------------|----------|----------|----------|----------|-------------------|
All files | 87.5 | 50 | 62.5 | 87.5 | |
convert.js | 50 | 100 | 0 | 50 | 2 |
error-handler.js | 50 | 100 | 0 | 50 | 2 |
index.js | 84.62 | 50 | 100 | 84.62 | 14,15 |
index.spec.js | 100 | 100 | 100 | 100 | |
request-converter.js | 50 | 100 | 0 | 50 | 2 |
----------------------|----------|----------|----------|----------|-------------------|
源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/47352972