ServerlessSpy

Lambda - ServerlessSpy

Lambda

Under the cover, ServerlessSpy intercepts Lambda events with Lambda internal extension.

Basic example:

await serverlessSpyListener.waitForFunctionMyLambdaRequest();

You can use conditions to wait for a particular event. You can also use generic (TestData) to strongly type the event.

await serverlessSpyListener.waitForFunctionMyLambdaRequest<TestData>({
  condition: (d) => d.request.id === myData.id,
});

Lambda produces three kinds of events: Request, Console, Response

await serverlessSpyListener.waitForFunctionMyLambdaRequest();
await serverlessSpyListener.waitForFunctionMyLambdaConsole();
await serverlessSpyListener.waitForFunctionMyLambdaResponse();

The Console event can be useful to validate intermediate processing steps. You write events with a simple console.log() method in the Lambda code.

You can chain calls for the same request:

await (
  await (
    await serverlessSpyListener.waitForFunctionMyLambdaRequest({
      condition: (d) => d.request.id === myData.id,
    })
  ).followedByConsole()
).followedByResponse();

The condition condition: (d) => d.request.id === myData.id finds the correct request and than you can use on each part getData() to get the event or any Jest functions to validate.

So a fully blown test would look like this:

(
  await (
    await (
      await serverlessSpyListener.waitForFunctionMyLambdaRequest<TestData>({
        condition: (d) => d.request.id === myData.id,
      })
    )
      .toMatchObject({
        request: myData,
      })
      .followedByConsole()
  )
    .toMatchObject({
      request: myData,
      console: {
        message: 'My console log message',
        optionalParams: [myData],
      },
    })
    .followedByResponse()
).toMatchObject({
  request: myData,
  response: {
    ...myData,
    message: `${myData.message} ServerlessSpy`,
  },

You can see all combinations in this test.