Skip to content

Instantly share code, notes, and snippets.

@wordyallen
Last active June 26, 2019 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wordyallen/6b0b1a42237107a0c4a09820a1a0c7ef to your computer and use it in GitHub Desktop.
Save wordyallen/6b0b1a42237107a0c4a09820a1a0c7ef to your computer and use it in GitHub Desktop.
  • 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.')))
    })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment