繁体   English   中英

使用玩笑模拟 aws-sdk S3#putObject 实例方法

[英]Mocking aws-sdk S3#putObject instance method using jest

对于包含以下内容的源代码:

 const S3 = require('aws-sdk/s3/clients')
 const s3 = new S3()
 s3.putObject(params, callback)

我根据这篇文章添加了以下模拟:

 jest.mock('aws-sdk/s3/clients')
 const S3 = require('aws-sdk/s3/clients')

 it('has to mock S3#putObject', () => { 
    S3.prototype.putObject.mockImplementation(() => cb()) 
 })

但是我找不到带/不带模拟的S3.prototype.putObject ,因为在此处apiLoader模式期间,api 的构建似乎有所不同。 但是, 这里的定义似乎完全不同

我也试过:

  const AWS = require('aws-sdk')
  console.log(AWS.S3.prototype.putObject) // undefined

如果我在原型上找不到它,我该如何模拟一个方法?

包装在 Promise 中会破坏结果

我已经将源代码包装在这样的 Promise 中:

new Promise((resolve, reject) => {
    s3.putObject(params, (err, data) => {
        if (err) {
            reject(err)
        } else {
           resolve(data)
       }
    })
})

并使用如下所示的测试:

const mockedPutObject = jest.fn();
jest.mock('aws-sdk/s3/clients', () => {
  return class S3 {
    putObject(params, cb) {
      mockedPutObject(params, cb);
    }
  }
});

it('should call aws S3.putObject method', async () => {
  const data = {
    Bucket: 'aaa',
    Key: 'bbb',
    Content: 'this can be anything',
    ACL: 'public-read'
  }
  await putObject(data)
  console.log(mockFn.calls)
  expect(mockFn).toBeCalledWith(data)
})

这导致错误 putObject › 具有适当的参数 › 应该调用 aws S3.putObject 方法

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

我认为将调用代码包装在手动承诺中或使用这样的库:

const {promisify} = require('es6-promisify')
const putS3Object = promisify(s3.putObject.bind(s3))
return putS3Object(data)

也同样失败。

对于源代码

//src.js
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3();

const putFunction = () => {
  s3.putObject(params, callback);
}
export default putFunction;

以下方法可用于模拟 S3 客户端的 putObject 方法。

const mockedPutObject = jest.fn();
jest.mock('aws-sdk/clients/s3', () => {
  return class S3 {
    putObject(params, cb) {
      mockedPutObject(params, cb);
    }
  }
});

it('has to mock S3#putObject', () => {
    const putFunc = require('./src).default.putFunc;
    putFunc();
    expect(mockedPutObject).toHaveBeenCalledWith(params, callback);
 })

你可以使用jest.fn().mockImplementation

// index.js
const AWS = require('aws-sdk')
const s3 = new AWS.S3()

s3.putObject({},()=> {
  return 2;
});

// your test under test folder
let AWS = require('aws-sdk');
describe('test', () => {
  let result;
  beforeEach(()=>{
    AWS.S3 = jest.fn().mockImplementation( ()=> {
      return {
        putObject (params, cb) {
          result = cb();
        }
      };
    });
    require('../index');
  });
  test('call s3', () => {
    expect(result).toBe(2);
  });
});

如果您不想仅出于测试目的使用 AWS.S3 中的原型方法重新创建对象,我可以通过简单地添加以下内容来模拟实现:

// Arrange
const spy = jest.fn();
S3.prototype.getObject = spy;
// Act
...
//Assert
expect(spy).toHaveBeenCalledWith(data);

让我知道进展如何(即使这可能会迟到)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM