Javascript 回调中方法的Sinon加密存根
我正在尝试测试一个简单的函数,该函数使用nodejs加密库生成一个随机名称。我正在使用sinon在伪随机字节回调中剔除一个方法调用,但似乎没有调用该存根。例如: getFileName.js 测试(在摩卡咖啡中运行) 我希望上面的测试在调用Javascript 回调中方法的Sinon加密存根,javascript,node.js,sinon,Javascript,Node.js,Sinon,我正在尝试测试一个简单的函数,该函数使用nodejs加密库生成一个随机名称。我正在使用sinon在伪随机字节回调中剔除一个方法调用,但似乎没有调用该存根。例如: getFileName.js 测试(在摩卡咖啡中运行) 我希望上面的测试在调用createHash时抛出一次。如果我将crypto.createHash调用移到回调之外(在伪随机数调用之前),它就可以正常工作。我是个新手,所以我对sinon和nodejs的基本理解可能是完全错误的。任何帮助都将不胜感激。问题在于这是一个异步函数,所以测试
createHash
时抛出一次。如果我将crypto.createHash
调用移到回调之外(在伪随机数调用之前),它就可以正常工作。我是个新手,所以我对sinon和nodejs的基本理解可能是完全错误的。任何帮助都将不胜感激。问题在于这是一个异步函数,所以测试代码的其余部分在回调之前执行。这样,存根将在函数实际使用之前恢复
为了使它正常工作,您应该更新getFileName.js
,这样它会返回一个承诺-这样您就可以了
然后在你的测试中
// added async
it('Crypto Error: createHash', async () => {
const crypto = require('crypto');
const expectedError = new Error('stub error occurred');
let cryptoStub = sinon.stub(crypto, 'createHash').throws(expectedError);
let callback = sinon.spy();
await getFileName(null, null, callback);
// once we are here, the callback has already been executed and the promise that getFileName resolved.
cryptoStub.restore();
sinon.assert.calledWith(callback, expectedError);
});
没有调用
createHash()
的原因是,由于异步函数,您在回调调用完成之前进行了断言
使用async/await的承诺将起作用。另一种不涉及将模块更改为使用promise的方法是在回调中进行断言
it('Crypto Error: createHash', function (done) {
const crypto = require('crypto');
const expectedError = new Error('stub error occurred');
let cryptoStub = sinon.stub(crypto, 'createHash').throws(expectedError);
getFileName(null, null, function (err, hash) {
sinon.assert.match(err, expectedError);
cryptoStub.restore();
done();
});
});
这样,您就可以检查调用回调时是否出现了预期的错误。确认这一点的一种方法是,您可以将第4行更改为
。throws('some other error')
,测试将失败。您使用的测试框架是什么?我使用的是mochait,回调中的断言确实不涉及更新他的模块,但是我强烈建议将他的代码移动到与承诺一起工作。不仅用于测试(它将生成更干净的代码),而且用于他使用模块的任何时候——否则,在不涉及spagetti的情况下进行后续调用将更加困难code@Gonzalo.-我同意。只是问题特别提到了回调。
module.exports = (req, file, cb) => {
return new Promise((resolve, reject) => {
crypto.pseudoRandomBytes(32, (err, raw) => {
try{
cb(err, err ? undefined : crypto.createHash('MD5').update(raw).digest('hex'));
resolve();
} catch(err) {
reject(cb(err));
}
});
});
};
// added async
it('Crypto Error: createHash', async () => {
const crypto = require('crypto');
const expectedError = new Error('stub error occurred');
let cryptoStub = sinon.stub(crypto, 'createHash').throws(expectedError);
let callback = sinon.spy();
await getFileName(null, null, callback);
// once we are here, the callback has already been executed and the promise that getFileName resolved.
cryptoStub.restore();
sinon.assert.calledWith(callback, expectedError);
});
it('Crypto Error: createHash', function (done) {
const crypto = require('crypto');
const expectedError = new Error('stub error occurred');
let cryptoStub = sinon.stub(crypto, 'createHash').throws(expectedError);
getFileName(null, null, function (err, hash) {
sinon.assert.match(err, expectedError);
cryptoStub.restore();
done();
});
});