我的功能是
exports.downloadFromBucket = function(fileKey) {
const localPath = `${process.cwd()}/data/${fileKey}`
return new Promise((resolve, reject) => {
const localFile = fs.createWriteStream(localPath)
const awsStream = s3.getObject({
Bucket: process.env.UPLOAD_BUCKET,
Key: fileKey
})
.createReadStream()
.on('error', (err) => {
logger.info('Error downloading file', err)
return reject(err)
})
.on('finish', () => {
logger.info('Completed downloading')
return resolve(localPath)
})
.pipe(localFile)
})
}
我如何使用mocha
和sinon
为此编写单元测试?
答案 0 :(得分:1)
这可能不是最漂亮的解决方案,但假设您要模拟s3
和fs
并测试on('error')
和on('finish')
行为:
您可以使用自定义s3模拟类,使用sinon存储原始s3和fs并触发您要测试的事件。
// Custom S3 Mocking Library
class S3MockLibrary {
constructor() {
this.events = {};
}
getObject(options) {
return this;
}
createReadStream() {
return this;
}
on(event, func) {
this.events[event] = func;
return this;
}
pipe(file) {
return this;
}
emit(event, err) {
this.events[event](err);
}
}
测试('完成')
it('should verify', async () => {
const s3Mock = new S3MockLibrary();
const fsStub = sinon.stub(fs, 'createWriteStream').returns('success');
const s3Stub = sinon.stub(s3, 'getObject').returns(s3Mock);
// Emit the finish event async
setTimeout(() => {
s3Mock.emit('finish');
}, 0);
const result = await downloadFromBucket('test');
fsStub.restore();
s3Stub.restore();
sinon.assert.calledOnce(fsStub);
sinon.assert.calledOnce(s3Stub);
assert.equal(result, `${process.cwd()}/data/test`);
});
测试('错误)
it('should fail', async () => {
const s3Mock = new S3MockLibrary();
const fsStub = sinon.stub(fs, 'createWriteStream').returns('success');
const s3Stub = sinon.stub(s3, 'getObject').returns(s3Mock);
setTimeout(() => {
s3Mock.emit('error', 'testError');
}, 0);
let error;
await downloadFromBucket('test').catch((err) => {
error = err;
});
fsStub.restore();
s3Stub.restore();
sinon.assert.calledOnce(fsStub);
sinon.assert.calledOnce(s3Stub);
assert.equal(error, 'testError');
});