Closed aritranagnordcloud closed 2 years ago
Do we have any AWS CDK patterns for unit tests. Can we use the native mock libraries for the AWS Services Construct?
Hey @aritranagnordcloud,
This is probably because your tests don't have environment variables properly configured. Your tests don't read from your cdk.json
file; you have to set the context with something like the setContext()
method.
Let me know if that's not the cause here - and if it's not could you share your test code?
Here is the test code:
stackProps are the other values which are required to create the different construct in the cdk synth.
`
CdkStack stack = new CdkStack(app, "test", new StackProps.Builder() .env(CdkApp.makeEnv("accountno", "region")) .build(), stackProps); Template template = Template.fromStack(stack); template.hasResourceProperties("AWS::Logs::LogGroup", new HashMap<String, Number>() {{ put("RetentionInDays", 7); }}); `
I am not sure if cdk.json is being used in the test folder or how do i use that in the command. Also, the command to build the whole project is ./gradlew clean build test
any leads about the CDK Unit test package structure would be really helpful. Since i could not find any way to run the unit test
I am not sure if cdk.json is being used in the test folder or how do i use that in the command
For the CDK's tests that require environment variables to be set, we use the setContext()
method I linked above to set the appropriate context to the constructs that need it
Since i could not find any way to run the unit test
Here's our documentation page on testing CDK constructs https://docs.aws.amazon.com/cdk/v2/guide/testing.html
According to this page, this is the command you should be using to run tests:
mvn compile && mvn test
This issue seems to be very intermittent with the setup. Here is the setup for the code which is breaking:
RecordSet recordSet = new RecordSet(this, "PrivateRecord",
RecordSetProps.builder()
.recordName(id.concat("-app").concat(".")
.concat(stackProps.getDnsDomain()))
.recordType(RecordType.A)
.target(RecordTarget.fromAlias(new IAliasRecordTarget() {
@Override
public @NotNull AliasRecordTargetConfig bind(
@NotNull IRecordSet record) {
return AliasRecordTargetConfig.builder()
.dnsName(stackProps
.getCommonAlbDnsName())
.hostedZoneId(stackProps
.getCommonAlbHostedZoneId())
.build();
}
@Override
public @NotNull AliasRecordTargetConfig bind(
@NotNull IRecordSet record, IHostedZone zone) {
return null;
}
}))
.zone(HostedZone.fromHostedZoneAttributes(this, "ExistingHostedZone",
HostedZoneAttributes.builder()
.hostedZoneId(stackProps
.getDistributionZoneId())
.zoneName(stackProps.getDnsDomain())
.build()))
.build());
I checked the incoming props value and its working properly.
The error which is coming :
software.amazon.jsii.JsiiException: Got 'undefined' for non-optional instance of {"type":{"fqn":"@aws-cdk/aws-route53.AliasRecordTargetConfig"}}
Error: Got 'undefined' for non-optional instance of {"type":{"fqn":"@aws-cdk/aws-route53.AliasRecordTargetConfig"}}
at nullAndOk (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:9596:23)
at Object.deserialize (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:9315:25)
at Kernel._toSandbox (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:8783:69)
at Object.value (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:8611:41)
at new RecordSet (/tmp/jsii-kernel-Phx3Hv/node_modules/@aws-cdk/aws-route53/lib/record-set.js:100:79)
at /tmp/jsii-java-runtime6420813574840657886/lib/program.js:8432:58
at Kernel._wrapSandboxCode (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:8860:24)
at Kernel._create (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:8432:34)
at Kernel.create (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:8173:29)
at KernelHost.processRequest (/tmp/jsii-java-runtime6420813574840657886/lib/program.js:9757:36)
at app//software.amazon.jsii.JsiiRuntime.processErrorResponse(JsiiRuntime.java:124)
at app//software.amazon.jsii.JsiiRuntime.requestResponse(JsiiRuntime.java:95)
at app//software.amazon.jsii.JsiiRuntime.processCallbackResponse(JsiiRuntime.java:165)
at app//software.amazon.jsii.JsiiRuntime.requestResponse(JsiiRuntime.java:100)
at app//software.amazon.jsii.JsiiClient.createObject(JsiiClient.java:89)
at app//software.amazon.jsii.JsiiEngine.createNewObject(JsiiEngine.java:603)
at app//software.amazon.awscdk.services.route53.RecordSet.<init>(RecordSet.java:47)
Coming to the build and library plugin, we are. using gradle instead of maven
Do you have any examples of how to set the context forcibly on the app on the text folder. For example , when we invoke the same code from the src/main method , it works absolutely fine.
Any leads on this would be really helpful. I tried creating the unit tests in the following way:
App app = new App();
IBackendStackProps stackProps = new IBackendStackProps();
stackProps.setDnsDomain("test.domainname.com");
stackProps.setCommonAlbHostedZoneId("12345678");
stackProps.setCommonAlbDnsName("helloworld.region.elb.amazonaws.com");
stackProps.setDistributionZoneId("123456333455");
CdkStack stack = new CdkStack(app, "test", new StackProps.Builder()
.env(CdkApp.makeEnv("accountid", "region"))
.build(), stackProps);
Template template = Template.fromStack(stack);
template.hasResourceProperties("AWS::Route53::RecordSet", new HashMap<String, String>() {{
put("Type", A);
}});
When running mvn compile && mvn test
, its failing and generating the above error.
Do you have any examples of how to set the context forcibly on the app on the text folder.
Have you tried the SetContext()
method I've described above?
Here's an example of the CDK using this method to set the context in our tests https://github.com/aws/aws-cdk/blob/3721358fa1501e42b3514b8a8f15f05c9615f149/packages/%40aws-cdk/core/test/construct.test.ts#L163-L176
To do this with a Stack, you will also use Stack.node.setContext()
.
General Issue
CDK Unit tests failing for Lookups and existing Resources
The Question
Hi CDK team,
We have been using the Java CDK toolkit to create the solution construct for our application. We have an CDK construct which gets created using existing services like Route53 , VPC. For the normal cdk synth command without any test cases it works absolutely fine. While running the test cases via the AWS provided framework awscdk.assertions.Template. We could see the following error and results in failing the tests.
Actual code used :
Please help us in finding the solution to create the unit tests. Is the reason maybe due to disabling of lookups in the pipelines
Thanks, Aritra
CDK CLI Version
1.134.0
Framework Version
No response
Node.js Version
No response
OS
Mac
Language
Java
Language Version
java 11
Other information
No response