m-radzikowski / aws-sdk-client-mock

AWS JavaScript SDK v3 mocks for easy unit testing. 🖋️ Typed 🔬 Tested 📄 Documented 🛠️ Maintained
https://m-radzikowski.github.io/aws-sdk-client-mock/
MIT License
811 stars 40 forks source link

Multiple instantiations of class on same mock #235

Closed justin-masse closed 2 months ago

justin-masse commented 3 months ago

Hello,

I have a lambda that loops through 7-8 AWS accounts and assumes a role in each and then runs ListSecretsCommand using aws secretsmanager with SDKv3.

However, I am unable to efficiently set up the mock for ListSecretsCommand due to the fact that I do not pass it anything during instantiation. So I'm only able to set up my mock like:

for(const env of myEnvs) {
        secretsClientMock.on(ListSecretsCommand).resolves({
            SecretList: myAccountsSecretList.map(secretName => { 
                return { Name: `${env}${secretName}` }
            })
        })
    }

However, this loop causes it to only resolve the LAST value passed into the resolves(). It will not set up a watcher for EACH item in the loop? Is there a way around this? I do not know the exact ordering of myEnvs at all times (yes I could sort them but updating the code for a test is /vomit).

Ideally I could set a bunch of mock resolves and it wouldn't matter what order it would just match them 1:1 as they appear

m-radzikowski commented 2 months ago

However, this loop causes it to only resolve the LAST value passed into the resolves(). It will not set up a watcher for EACH item in the loop?

This is possible with resolvesOnce:

const mock = mockClient(S3Client);
mock.on(HeadObjectCommand).resolvesOnce({VersionId: "1"}).resolvesOnce({VersionId: "2"});

const s3 = new S3Client();

console.log(await s3.send(new HeadObjectCommand({Bucket: 'bucket', Key: 'key'})));
console.log(await s3.send(new HeadObjectCommand({Bucket: 'bucket', Key: 'key'})));

I do not know the exact ordering of myEnvs at all times

In this case, you should use callsFake() to produce dynamic response:

const mock = mockClient(S3Client);
mock.on(HeadObjectCommand).callsFake((input) => {
  return {VersionId: input.Key + "Version"};
});

const s3 = new S3Client();

console.log(await s3.send(new HeadObjectCommand({Bucket: 'bucket', Key: 'key1'})));
console.log(await s3.send(new HeadObjectCommand({Bucket: 'bucket', Key: 'key2'})));

Please reopen if that does not answer your question.