我如何在Node.js中存储S3上传?
为了洞察力,我使用Mocha进行测试,使用Sinon进行存根,但我可以改变任何事情。我有一个文件导出执行上传的功能。它看起来像这样:
var AWS = require('aws-sdk');
var s3 = new AWS.S3({ params: { Bucket: process.env.S3_BUCKET }});
var params = { Key: key, Body: body };
s3.upload(params, function (error, data) {
// Handle upload or error
});
如果我尝试存根AWS.S3
或AWS.S3.prototype
,则不会发生任何变化。我认为这是因为我的测试本身需要aws-sdk
并拥有自己的每个函数的副本。
我的测试看起来像这样:
describe('POST /files', function () {
var url = baseURL + '/files';
it('uploads the file to s3', function (done) {
var fs = require('fs');
var formData = {
video: fs.createReadStream(process.cwd() + '/test/support/video.mp4')
};
var params = {url: url, formData: formData};
request.post(params, function (error, response, body) {
expect(response.statusCode).to.eq(200);
expect(response.body).to.eq('Uploaded');
done();
});
});
});
此测试工作正常,但它不会将上传存根到S3,因此上传实际上会通过:X。
答案 0 :(得分:2)
如果您愿意,可以使用Sinon.js存根,如下所示:
公开AWS.S3
实例:
var AWS = require('aws-sdk');
var s3 = new AWS.S3({ params: { Bucket: process.env.S3_BUCKET }});
var params = { Key: key, Body: body };
exports.s3.upload(params, function (error, data) {
});
//Expose S3 instance
exports.s3 = s3;
像这样存储相同的实例:
var sinon = require('sinon');
//Import module you are going to test
var UploadService = require('./uploadService');
describe('POST /files', function () {
before(function() {
//Stub before, and specify what data you'd like in the callback.
this.uploadS3Stub = sinon.stub(uploadService.s3, 'upload').callsArgWith(1, null, { data: 'Desired response' });
});
after(function() {
//Restore after
this.uploadS3Stub.restore();
});
var url = baseURL + '/files';
it('uploads the file to s3', function (done) {
var fs = require('fs');
var formData = {
video: fs.createReadStream(process.cwd() + '/test/support/video.mp4')
};
var params = {url: url, formData: formData};
var self = this;
request.post(params, function (error, response, body) {
expect(response.statusCode).to.eq(200);
expect(response.body).to.eq('Uploaded');
//You can also check whether the stub was called :)
expect(self.uploadS3Stub.calledOnce).to.eql(true);
done();
});
});
});
答案 1 :(得分:1)
在Node中模拟S3有几种选择。
特定于S3的一些模块:
一般AWS模拟的一些模块:
你甚至可以启动一个响应某些S3 API调用的简单服务器:
最后一个可以很容易地用于其他语言和运行时,不仅仅是在Node中。
答案 2 :(得分:0)
您需要使用sinon创建存根,并替换您使用存根进行测试的代码中的变量。有几个模块可以执行此操作,请尝试Mockery或Rewire。例如,使用Rewire,您可以使用rewire
而非require
加载要测试的模块,然后使用__set__
设置变量。
var rewire = require('rewire');
var moduleUnderTest = rewire('myModule');
moduleUnderTest.__set__('s3', stubbedS3);
答案 3 :(得分:0)
s3UploadStub = AWS.S3.prototype.upload = sandbox.stub();
it("should upload successfully", async function() {
s3UploadStub.yields(null, data);
let response = await FileUtil.uploadFile(fileReference,data);
expect(s3UploadStub.calledOnce).to.be.true;
expect(response.statusCode).to.equal(200);
expect(response.body).to.equal(fileReference);
});