node.js:如何使用sinon对AWS s3 getobject进行存根

时间:2018-08-22 04:22:54

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

我正在尝试编写单元测试,但是无法对AWS S3 getobject方法进行存根处理。这是我的代码:

describe('testExecuteSuccess()', function () {
    it('Test execution with id is successful.', async () => {
        let id = "test_id";
        const getObjectStub = AWS.S3.prototype.getObject = sinon.stub();
        getObjectStub.returns({ promise: () => Promise.resolve({ Body: "test" }) });
        await executionHandler.execute(id).then(() => {
            getObjectStub.should.have.been.calledOnce;
        });
    });
});

有人知道它有什么问题吗/如何正确地存根getObject方法?运行测试时,我得到InvalidParameterType: Expected params.Bucket to be a string,它证明存根不起作用。

这是executionHandler.execute方法的代码:

exports.execute = async function(curr_id) {
    let params = { Bucket: BUCKET_NAME, Key: KEY_PATH }
    let fileObject = await s3.getObject(params).promise();
    let codeId = executeCode(fileObject).id;
    if (codeId !== curr_id) {
        throw "Id from executed code does not match currentId: " + curr_id;
    }
}

注意:我正在使用Mocha测试运行程序。

1 个答案:

答案 0 :(得分:0)

您可以使用 link seams 删除依赖项,例如 aws-sdk 模块。这是 CommonJS 版本,因此我们将使用 proxyquire 来构建接缝。

单元测试解决方案:

main.js

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

exports.execute = async function (curr_id) {
  const BUCKET_NAME = 'examplebucket';
  const KEY_PATH = 'SampleFile.txt';
  let params = { Bucket: BUCKET_NAME, Key: KEY_PATH };
  let fileObject = await s3.getObject(params).promise();
  let codeId = executeCode(fileObject).id;
  if (codeId !== curr_id) {
    throw 'Id from executed code does not match currentId: ' + curr_id;
  }
};

function executeCode(file) {
  return file;
}

main.test.js

const proxyquire = require('proxyquire');
const sinon = require('sinon');
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);
const { expect } = chai;

describe('51959840', () => {
  afterEach(() => {
    sinon.restore();
  });
  it('should do nothing if codeId is equal with curr_id', async () => {
    const fileObject = { id: '1' };
    const s3Mock = {
      getObject: sinon.stub().returnsThis(),
      promise: sinon.stub().resolves(fileObject),
    };
    const AWSMock = { S3: sinon.stub().returns(s3Mock) };
    const { execute } = proxyquire('./main', {
      'aws-sdk': AWSMock,
    });
    await execute('1');
    sinon.assert.calledOnce(AWSMock.S3);
    sinon.assert.calledWithExactly(s3Mock.getObject, { Bucket: 'examplebucket', Key: 'SampleFile.txt' });
    sinon.assert.calledOnce(s3Mock.promise);
  });

  it('should throw error if codeId is NOT equal with curr_id', async () => {
    const fileObject = { id: '2' };
    const s3Mock = {
      getObject: sinon.stub().returnsThis(),
      promise: sinon.stub().resolves(fileObject),
    };
    const AWSMock = { S3: sinon.stub().returns(s3Mock) };
    const { execute } = proxyquire('./main', {
      'aws-sdk': AWSMock,
    });
    await expect(execute('1')).to.rejectedWith('Id from executed code does not match currentId: 1');
    sinon.assert.calledOnce(AWSMock.S3);
    sinon.assert.calledWithExactly(s3Mock.getObject, { Bucket: 'examplebucket', Key: 'SampleFile.txt' });
    sinon.assert.calledOnce(s3Mock.promise);
  });
});

单元测试结果:

  51959840
    ✓ should do nothing if codeId is equal with curr_id (2884ms)
    ✓ should throw error if codeId is NOT equal with curr_id


  2 passing (3s)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 main.js  |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

包版本:

"proxyquire": "^2.1.3",
"sinon": "^8.1.1",
"aws-sdk": "^2.817.0",