Mock promisified AWS service operation calls with Jest

At Mbanq we run most of our services on AWS and try to use AWS Lambda as much as possible.
Lately I’ve been working on the a small npm package that will help us make use of SSM and KMS to manage our system configuration. SSM and KMS play nicely together as the most of AWS services.
In order to test the newly written npm package, we had to mock the promisified version of the ssm.getParameters(request)
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. For example there is the aws-mock-sdk package from the very cool DWYL guys. I decide to go with pure Jest though.

Some things you have to take 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 mockedssm
whenever you write your tests. Sure you could alsomodule.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 regularexpect(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 may want to mock a successful response from the ssm.getParameters(request).promise()
or to mock 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.
const AWS = require('aws-sdk')
let ssm = new AWS.SSM()
const ssmPromise = {
promise: jest.fn().mockImplementation((request) => {
return new Promise((resolve, reject) => {
const response = {
Parameters: [
{
Name: 'bar',
Type: 'String',
Value: 'barfoorista',
Version: 1,
LastModifiedDate: '2018-08-22T13:49:55.717Z',
ARN: 'arn:aws:ssm:eu-west-1:whatever:parameter/bar'
},
{
Name: 'foo',
Type: 'String',
Value: 'foobarista',
Version: 1,
LastModifiedDate: '2018-08-22T13:49:41.486Z',
ARN: 'arn:aws:ssm:eu-west-1:whatever:parameter/foo'
}
],
InvalidParameters: []
}
resolve(response)
})
})
}
ssm = { getParameters: () => { return ssmPromise } }
Throw an Error
By using the ssm
instance you created at the top of your test, you can also mock the ssm.getParameters()
in one go.
Here is an example of how you could mock ssm.getParameters()
throwing an Error
ssm = {
getParameters: () => {
return {
promise: jest.fn().mockImplementation((request) => {
return new Promise((resolve, reject) => {
return reject(new Error('foobar'))
}).catch(() => console.log('Ok'))
})
}
}
}
In a gist
(pun intended) you can see part of the test, we’re using to test our package.
The package is still work in progress. Once it’s release you’ll be able to install it by running npm i --save sreda