nteg-tests-alpha: assert response from invokeFunction call
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
I am trying to write some CDK integration tests, making use of the @aws-cdk/integ-tests-alpha package. In these tests, I have created a custom lambda that allows us to perform HTTP calls to health check endpoints for some resources that are only accessible within the VPC.
However, I am having issues getting the integ-tests-alpha framework to parse the response from the lambda correctly. Note that each of the below examples successfully run the cloudformtion deployment/tests, but the test stack output always shows a failed test, seemingly due to how the result from the lambda is passed back to cloudformation.
I have confirmed that the lambda is deployed and is returning a response along the lines of what I'm expecting, which looks like:
```
{
"statusCode": 200,
"body": {
"message": "Success",
"data": {
...
}
}
}
```
I have tried a number of ways to parse this response using the provided mothods that are available to the invokeFunction() command in the integ-tests-alpha framework, but they all return some sort of error. Below is what I've tried and the return results:
Attempt 1
```
const lambdaInvoke = integ.assertions.invokeFunction(...)
lambdaInvoke.expect(ExpectedResult.objectLike({
Payload: {
statusCode: 200,
body: {
message: "success"
}
}
}))
results from cloudformation output:
{"status":"fail","message":"{\n \"ExecutedVersion\": \"$LATEST\",\n!! Expected type object but received string\n \"Payload\": \"{\\\"statusCode\\\": 200, \\\"body\\\": {\\\"message\\\": \\\"Success\\\", \\\"data\\\": {...}}"
```
Attempt 2:
```
const lambdaInvoke = integ.assertions.invokeFunction(...)
lambdaInvoke.expect(ExpectedResult.stringLikeRegexp('"statusCode":200'))
results from cloudformation output:
{"status":"fail","message":"!! Expected a string, but got 'object'\n!! String '[object Object]' did not match pattern '\"statusCode\":200'\n{\n \"ExecutedVersion\": \"$LATEST\",\n \"Payload\": \"{\\\"statusCode\\\": 200, \\\"body\\\": {\\\"message\\\": \\\"Success\\\", \\\"data\\\": {...}}"
```
I have also tried both:
```
const lambdaInvoke = integ.assertions.invokeFunction(...)
.assertAtPath('message', ExpectedResult.objectLike({
Payload: {
statusCode: 200,
body: {
message: "success"
}
}
}))
returns: "message":"!! Expected type object but received undefined\nundefined"
```
and
```
const lambdaInvoke = integ.assertions.invokeFunction(...)
.assertAtPath('message', ExpectedResult.stringLikeRegexp('"statusCode":200'))
returns "message":"!! Expected a string, but got 'undefined'\n!! String 'undefined' did not match pattern '\"statusCode\":200'\nundefined"
```
I have also tried both of the above `.assertAtPath()` commands with the 'message.Payload' path, but I get the same results.
It appears that there is not a method in the ExpectedResult class that can parse the payload that is returned by the `.invokeFunction()` call.
The documentation does not seem to elaborate in any way on how to parse the returned result from the lambdaInvoke function. There seems to be missing examples on the lambdaInvoke [assertAtPath](https://docs.aws.amazon.com/cdk/api/v2/docs/@aws-cdk_integ-tests-alpha.LambdaInvokeFunction.html#assertwbratwbrpathpath-expectedspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan) documentation which looks like it should be giving an example
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
Methods implemented by the ExpectedResult class should be able to parse the payload returned by the `.invokeFunction()` assertion.
### Current Behavior
Methods implemented by the ExpectedResult class cannot parse the payload returned by the `.invokeFunction()` assertion. The methods appear to require a strict format to be returned by the underlying API call that the `.invokeFunction()` call does not adhere to
### Reproduction Steps
Create a Lambda function that returns an arbitrary response object.
Create a new CDK integration test stack using the @aws-cdk/integ-tests-alpha package
Call the Lambda function using the `invokeFunction()` method:
```
const lambdaInvoke = integ.assertions.invokeFunction({
functionName: <>,
invocationType: InvocationType.REQUEST_RESPONSE
})
```
Expect some result back:
```
lambdaInvoke.expect(ExpectedResult.objectLike({
<>
}))
```
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### AWS CDK Library version (aws-cdk-lib)
aws-cdk-lib@2.200.1
### AWS CDK CLI version
2.1019.1 (build d758c9f)
### Node.js Version
v23.10.0
### OS
Windows 10 22H2
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Reproduce the integration test using @aws-cdk/integ-tests-alpha invokeFunction(), ExpectedResult, and assertAtPath() with the shown Lambda response. Start by comparing the CloudFormation output’s string Payload with the values those matchers receive, then review the LambdaInvokeFunction assertAtPath documentation. Done means the returned payload can be asserted reliably or the documentation clearly explains the required format.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100