如何使用sinon模拟AWS S3 getObject

时间:2018-10-19 11:03:41

标签: javascript amazon-web-services unit-testing amazon-s3 sinon

我正在尝试对从存储桶返回S3对象的重新调整路由进行单元测试

我的路线是:

module.exports = function(server) {
  server.get('/configs/:version', (req, res, next) => {
    const s3 = new AWS.S3();

    const params = {
      Bucket: 'testBucket',
      Key: 'testKey'
    };

    function send(data, next) {
      res.setHeader('Content-Type', 'text/plain');
      res.setHeader('Cache-Control', 'no-cache');
      res.status(200);
      res.send(data.Body);
      next();
    }

    s3.getObject(params, (err, data) => (err) ? next(err) : send(data, next));
  });
};

对于我的单元测试,我一直在尝试模拟S3构造函数,以便可以对getObject进行存根处理,并且失败了。

describe('#configs', () => {
  let req;
  let res;
  let next;
  let server;
  let config;
  let AWS;
  let S3;
  let route;

  beforeEach(() => {
    req = {
      params: {
        version: 'testVersion'
      }
    };

    res = {
      send: sinon.spy(),
    };

    next = sinon.spy();

    server = {
      get: sinon.stub(),
    };

    config = {
      get: sinon.stub(),
    }

    AWS = () => {
      return {
        S3: () => {
          return {
            getObject: sinon.stub()
          }
        }
      }
    }

    route = proxyquire(process.cwd() + '/lib/routes/configs/get', {
      'configs.js': config,
      'aws-sdk': AWS,
    });

    route(server);
  });

  describe('#GET', () => {
    it('Should register configs get route', () => {
      let s3 = sinon.createStubInstance(AWS.S3, {
        getObject: sinon.stub(),
      });

      server.get.callArgWith(1, req, res, next);
      expect(server.get).calledOnce.calledWith('/configs/:version');
      expect(s3.getObject).calledOnce.calledWith({
        Bucket: 'testBucket',
        Key: 'testKey'
      });
    });
  });
});

但是我得到这个错误: TypeError: undefined is not a spy or a call to a spy!在getObject方法上。 一遍又一遍地阅读了sinon文档之后,我不明白如何模拟构造函数,如何对getObject方法进行存根,这样才能确保它被正确调用并返回,所以我知道它的响应得到了正确的处理有人可以帮忙吗我有这个吗?

1 个答案:

答案 0 :(得分:1)

最后,我发现了问题所在,我试图模拟构造函数,而不是仅模拟所需的方法。因此,我最终只需要S3没有配置就可以进行单元测试:

const S3 = require('aws-sdk').S3;

模拟所需的方法:

S3.prototype.getObject = sinon.stub();

实例化构造函数:

s3 = new S3();

并测试该对象:

expect(s3.getObject).calledOnce.calledWith({
    Bucket: 'testBucket',
  Key: 'testKey'
});