【问题标题】:Stubbing S3 uploads in Node.js在 Node.js 中存根 S3 上传
【发布时间】:2015-12-30 01:12:15
【问题描述】:

如何在 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.S3AWS.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。

【问题讨论】:

  • 如果有帮助,您可以替换 AWS 开发工具包使用的主机,而不是存根,以便它使用虚拟主机。还有一些用于模拟 S3 的服务器,您可以在本地运行。
  • @Brad 如果存根不起作用,那绝对是一个选择。 ://

标签: node.js amazon-s3 mocha.js sinon


【解决方案1】:

您需要使用 sinon 创建存根,并用存根替换您正在测试的代码中的变量。有几个模块可以做到这一点,试试MockeryRewire。例如,使用 Rewire 您可以使用 rewire 而不是 require 加载您正在测试的模块,然后使用 __set__ 设置变量。

var rewire = require('rewire');
var moduleUnderTest = rewire('myModule');
moduleUnderTest.__set__('s3', stubbedS3);

【讨论】:

    【解决方案2】:

    如果您愿意,可以使用Sinon.js 存根,如下所示:

    1. 公开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;
      
    2. 像这样存根相同的实例:

      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();
          });
        });
      });
      

    【讨论】:

    • 旧答案,但值得注意的是它按承诺工作。只有一个音符 - 它的 sinon.stub 不是 Sinon.stub
    • 嘿@LiviuR,更新了答案,现在是sinon.stub。也不妨看看stackoverflow.com/questions/26243647/… 建议的答案,因为它似乎比直接使用 sinon 更受欢迎
    【解决方案3】:

    有几个选项可以在 Node 中模拟 S3。

    一些特定于 S3 的模块:

    一些用于一般 AWS 模拟的模块:

    您甚至可以启动一个简单的服务器来响应一些 S3 API 调用:

    最后一个可以很容易地在其他语言和运行时中使用,而不仅仅是在 Node 中。

    【讨论】:

      【解决方案4】:
      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);
          });
      

      【讨论】:

        猜你喜欢
        • 2021-12-14
        • 2017-02-17
        • 2020-12-30
        • 1970-01-01
        • 1970-01-01
        • 2021-09-26
        • 1970-01-01
        • 2018-08-29
        • 2020-03-15
        相关资源
        最近更新 更多