dwyl/aws-sdk-mock

[Feature request] Allow initializing the AWS Services outside of the handler

albertodiazdorado opened this issue · 5 comments

I quote from the README:

NB: The AWS Service needs to be initialised inside the function being tested in order for the SDK method to be mocked e.g for an AWS Lambda function example 1 will cause an error region not defined in config whereas in example 2 the sdk will be successfully mocked.

Now I also quote from the Lambda best practices as published by AWS:

Take advantage of execution environment reuse to improve the performance of your function. Initialize SDK clients and database connections outside of the function handler (...)

I love this testing package, but it makes me very sad that I have to choose between following Lambda best practices or using this amazing testing framework. I want to initialize AWS services outside of the hanlder so that lambdas (warm) start faster, but then I cannot use aws-sdk-mock :(

Or: maybe documenting memoization patterns that work with this?

@onyxraven what are the memoization patters you refer to?

a possibility for (brief, untested) example:

let dynamoClient = undefined;

function getDynamoClient() {
  if (dynamoClient != undefined) { return dynamoClient; }
  return dynamoClient = new AWS.DynamoDB();
}

export function handler(e, c) {
  let dynamo = getDynamoClient();
  theRest(e);
}

@onyxraven thank you for your input, but will this work? Does the memoization work between lambda invokations? Intuitively I would say that it doesn't, but I haven't tested it either.

Ideally you would be able to use AWS Services as recommended by AWS (i.e. initializing the service outside of the function handler), and aws-sdk-mock would work seamless with that.

Agree, though order of operations gets tricky, since it will require you to mock the object before the first require of the code so that the execution catches the mock.

I'm getting some extra opinion, but as far as I understand, because dynamoClient has scope outside handler, it will be persisted through the life of the container, like doing new outside of handler will too. I'll follow up with my further findings.

One note, I didn't touch on that there needs to be a reset() style method here - to clear the memoized object for testing, so that you can get a new mock by calling new again.