Description
Describe the bug
There doesn't seem to be a nice way to test getSignedUrl from @aws-sdk/s3-request-presigner. Using sinon to try and stub out the function results in TypeError: Descriptor for property getSignedUrl is non-configurable and non-writable
from this code:
const s3RequestSigner = require("@aws-sdk/s3-request-presigner");
const expect = require('chai').expect;
const sinon = require('sinon')
....
it('should throw an error when getSignedUrl rejects', async function() {
const sandbox = sinon.createSandbox();
sandbox.stub(s3RequestSigner, "getSignedUrl").rejects("fakeUrl");
sandbox.restore();
})
This is because sinon throws when obj.prop is a synthetic getter: sinonjs/sinon#2377
Expected Behavior
I would expect that I can mock getSignedUrl to resolve or reject however I want using something like sinon to stub/spy/mock out the functionality.
Current Behavior
Sinon throws TypeError: Descriptor for property getSignedUrl is non-configurable and non-writable
Reproduction Steps
Create a test environment using jasmine or mocha, install sinon, chai, @aws-sdk/s3-request-presigner and @aws-sdk/client-s3. Try and mock out getSignedUrl with code such as:
const s3RequestSigner = require("@aws-sdk/s3-request-presigner");
const expect = require('chai').expect;
const sinon = require('sinon')
describe('trying to mock getSignedUrl', () => {
it('should throw an error when getSignedUrl rejects', async function() {
const sandbox = sinon.createSandbox();
sandbox.stub(s3RequestSigner, "getSignedUrl").rejects("fakeUrl");
sandbox.restore();
})
})
Possible Solution
Not a solution for Amazon, but for anyone else struggling with this issue, you can use proxyquire to replace s3-request-presigner like thus:
const sinon = require('sinon')
const proxyquire = require('proxyquire')
...
it('should throw an error when getSignedUrl rejects', async function() {
const fakeurl = 'hello world'
const fakeURL = sinon.stub().resolves(fakeurl)
const handler = proxyquire(
'../../handlers/presigned_url',
{
'@aws-sdk/s3-request-presigner': {
'getSignedUrl': async () => {
return fakeURL()
}
}
}
)
})
But you might run into other issues depending on how your tests and code is written.
Additional Information/Context
No response
SDK version used
3.109.0
Environment details (OS name and version, etc.)
node.js 16, sinon 14.0.0, chai 4.3.6, jasmine 4.2.0, OS X 12.2.1