Mock promisified AWS service operation calls with Jest
Apr 10, 2021
At Mbanq Cloud we run most of our services on AWS and try to use AWS Lambda as much as possible.
A while ago I’ve been working on the a small npm package that should have helped us to make use of SSM and KMS to manage our system configuration. SSM and KMS play nicely together as the most of the AWS services.
In order to test the newly written npm package, I had to mock the promisified version of the ssm.getParameters(request)
1 2 3
const AWS = require('aws-sdk') const ssm = AWS.SSM({ region: 'eu-west-1 }) ssm.getParameters(request).promise() // we have to mock the response from this call
There are different ways of mocking the AWS JS SDK calls. For example there is the aws-mock-sdk package from the very cool DWYL guys. I decided to go with pure Jest implementation though.
There are some things to be taken into account to make the SSM’s functionality testable:
Use ssm as a parameter in your function call, e.g. const load = (ssm, keys, expiryMs) It will help you to use the mocked ssm whenever you write your tests. Sure you could also module.exports = { ssm } alongside other functions you want to export but I didn’t really like this idea
If you wanna check for the errors thrown inside of an async/await function you have to use: expect(yourFunc()).rejects.toEqual(new Error('Error Message')) . The regular expect(yourFunc()).toThrowError('Error Message')**WON’T WORK**
Ok, now you’re probably asking yourself:
How the heck do you mock the promisified AWS service operation calls?
You will either want to mock a successful response from the ssm.getParameters(request).promise() or the Error thrown by the this function call.
Successful response
First, create a js object with the promise key and mock the value of the promise with the jest.fn().mockImplementation() that will return a Promise that when resolved return a successful response.
Then return the created ssmPromise whenever you make a call to getParameters() function.
it(`throws an error if no keys are providerd`, async () => { functionthrowsErr () { read(ssm, []) } expect(throwsErr).toThrowError(`You need to provide a non-empty array of config keys`) })
it(`throws an error if some keys are missing`, async () => { expect(keys(ssm, ['foobar'])).rejects.toEqual(newError(`Missing SSM Parameter Store keys: foobar`)) })
it(`throws an error when ssm is throwing one`, async () => { ssm = { getParameters: () => { return { promise: jest.fn().mockImplementation((request) => { returnnewPromise((resolve, reject) => { return reject(newError('foobar')) }).catch(() =>console.log('Ok')) }) } } } expect(keys(ssm, ['foo'])).rejects.toEqual(newError(`TypeError: Cannot destructure property \`Parameters\` of 'undefined' or 'null'.`)) }) })
The sreda package is in the dev mode. Check it out if you would like to use it in you serverless project: https://www.npmjs.com/package/sreda