aws-sdk-mock: getSignedUrl doesn't mock correctly when called asynchronously

code:

AWSMock.mock('S3', 'getSignedUrl', 'message');
const s3 = new AWS.S3({ paramValidation: true }),
const s3Url = s3.getSignedUrl('getObject', {Key: 'key', Bucket: 'Bucket'});
console.log(s3Url); //should be a string... However it looks more like an AWS Request object:

Output:

{ promise: [Function],
  createReadStream: [Function: createReadStream],
  on: [Function: on],
  send: [Function: send] }

Please review the documentation for further information: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 32
  • Comments: 16

Most upvoted comments

I had the same issue with this code:

const url = s3.getSignedUrl('putObject', s3Params)

and my test:

AWS.mock('S3', 'getSignedUrl', (action, _params, callback) => {
  console.log('S3', 'getSignedUrl', 'mock called')
  callback(null, mockSignedUrl)
})

so, I changed my code to this, and then my test worked!

const url = await s3.getSignedUrlPromise('putObject', s3Params)

we should not change implementation of our code to pass tests but rather the aws-sdk-mock should support mocking of all features of aws-sdk

It seems this has something to do with the assumption that all the AWS service methods should have the signature service(params, callback)

getSignalUrl has the following signature: getSignalUrl(method,params, callback)

I’d really appreciate it if this could be fixed

Just ran over this issue on a project and @yoelfme 's approach was very helpful for my case, with the difference that i already was using the s3.getSignedUrlPromise method, so i just had to create a mock for s3.getSignedUrl and that was enough for the test to work without problems.

It seems that this library only mocks methods that return instances of the Request<D, E> class. However, there are lots of methods that don’t return such instances, for example, the aforementioned getSignedUrl. Are there future plans to add the possibility to mock such methods?

Also experiencing this issue.

So I ran into this issue also, I was able to get around it for now with mocking the getSignedUrlPromise function manually:

test('will return a 200', async () => {
    const listObjectsV2Mock = jest.fn().mockReturnValue({
      promise: jest.fn().mockResolvedValue({
        Contents: [
          {
            Key: 'testing/',
            LastModified: '2020-03-14T01:24:24.000Z',
            ETag: '"d41d8cd98f00b204e9800998ecf8427e"',
            Size: 0,
            StorageClass: 'STANDARD'
          }
        ]
      })
    });

    const putObjectMock = jest.fn().mockReturnValue({
      promise: jest.fn().mockResolvedValue({})
    });

    const getSignedUrlPromise = jest
      .fn()
      .mockResolvedValue('Successfully Mocked URL');

    AWSMock.mock('S3', 'getSignedUrlPromise', (operation, params, callback) => {
      return callback(null, 'test');
    });

    AWS.S3 = jest.fn().mockImplementation(() => ({
      getSignedUrlPromise,
      listObjectsV2: listObjectsV2Mock,
      putObject: putObjectMock
    }));

    const { exportDataToCsv } = require('./exportDataToCsv');
    const result = await exportDataToCsv({}, {});
    expect(result).toBe({ statusCode: 200 });
  }); 

This allowed me to mock the getSignedUrlPromise function whilst also mocking others. The issue I had with the others was when I injected the manually mocked functions whilst using aws-sdk-mock I was losing all reference to the stubs previously in place, so I have simply not used this repo for this functions unit tests. Not a great solution but might be helpful for others that need a solution now.