For the source code containing:
const S3 = require('aws-sdk/s3/clients')
const s3 = new S3()
s3.putObject(params, callback)
I have added the following mock based on this article:
jest.mock('aws-sdk/s3/clients')
const S3 = require('aws-sdk/s3/clients')
it('has to mock S3#putObject', () => {
S3.prototype.putObject.mockImplementation(() => cb())
})
But I cannot find the S3.prototype.putObject
with / without mocking because the api seems to be built differently during an apiLoader
pattern here.
However, the definitions seem completely different here
I also tried with:
const AWS = require('aws-sdk')
console.log(AWS.S3.prototype.putObject) // undefined
How can I mock a method if I cannot find it on the prototype?
Wrapping in Promise breaks outcome
I have wrapped the source code in a Promise like this:
new Promise((resolve, reject) => {
s3.putObject(params, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
and using the test that looks like this:
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)
})
which results in an Error putObject › with appropriate params › should call aws S3.putObject method
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
I think wrapping the calling code in a hand-rolled promise or using a library like this:
const {promisify} = require('es6-promisify')
const putS3Object = promisify(s3.putObject.bind(s3))
return putS3Object(data)
also fails similarly.
For the source code
//src.js
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3();
const putFunction = () => {
s3.putObject(params, callback);
}
export default putFunction;
Following approach can be used to mock the putObject method of S3 client.
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);
})