- Given we use the AWS sdk frequently and assuming we have to mock out the API.
- Given typescript enforces strict null checking. We must create branches to check the shape of the data return data
In the following example the SDK should return the following object:
{ CertificateSummaryList: [{ DomainName: '12344.foo.bar', CertificateArn: 'arns:aws:mars:12323', ... }]}
The exmaple task is to find the certificate where the subdomain of the DomainName property includes the account id.
getCertARN.ts
export const getCertARN: Handler = async (
event: CloudFormationCustomResourceEvent,
context: Context,
) => {
const region = event.StackId.split(':')[3]
const acm = new AWS.ACM({ region })
const data = await acm.listCertificates().promise()
if (!data || !data.CertificateSummaryList) {
throw new Error('Could not get list of certificates.')
}
const cert = data.CertificateSummaryList
.find(c => {
if (!c || !c.DomainName) {
throw new Error('Could not get domain name.')
}
const accountId = event.StackId.split(':')[4]
return c.DomainName.includes(accountId)
})
if (!cert || !cert.CertificateArn) {
throw new Error('Could not get certificate ARN.')
}
return send(event, context, SUCCESS, { arn: cert.CertificateArn })
}
From the snippet above you'll note that there is 3 null checks. Each of these checks must tested. The following is one way to test those branches
getCertARN.spec.ts
// create mock responses for each of the 3 branches
const mockListCertificate = jest.fn()
.mockReturnValueOnce({ promise: jest.fn().mockResolvedValueOnce({
CertificateSummaryList: [ { DomainName: '123456789012.foo.bar', CertificateArn: mockCertificateArn } ],
})})
.mockReturnValueOnce(({ promise: jest.fn().mockResolvedValueOnce({}) }))
.mockReturnValueOnce(({ promise: jest.fn().mockResolvedValueOnce({
CertificateSummaryList: ['bogus'],
})}))
.mockReturnValueOnce(({ promise: jest.fn().mockResolvedValueOnce({
CertificateSummaryList: [{ DomainName: '123456789012.foo.bar' }],
})}))
// test each branch
...
it('returns bad responses when trying to filter the cert arn', async () => {
await LambdaTester(getCertARN)
.event(mockEvent)
.context({})
.expectReject(err => expect(err).toEqual(Error('Could not get list of certificates.')))
await LambdaTester(getCertARN)
.event(mockEvent)
.context({})
.expectReject(err => expect(err).toEqual(Error('Could not get domain name.')))
await LambdaTester(getCertARN)
.event(mockEvent)
.context({})
.expectReject(err => expect(err).toEqual(Error('Could not get certificate ARN.')))
})