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{:target="_blank"}.