Search code examples
amazon-s3aws-cdkaws-cdk-java

Unit testing LifecycleConfiguration AWS CDK Java


I created a new s3 bucket and add a lifecycle rule to it:

Bucket bucket = new Bucket(this, "MyS3Bucket", bucketProperties());
bucket.addLifecycleRule(LifecycleRule.builder().enabled(true).expiration(Duration.days(7)).build());

Now I am trying to test it like that:

template.hasResourceProperties("AWS::S3::Bucket",
        Match.objectLike(Map.of(
            "LifecycleConfiguration", Collections.singletonList(
                Collections.singletonMap(
                    "Rules", Map.of(
                        "ExpirationInDays", "7",
                        "Status", "Enabled"
                    )))
        ))
    );

But I got next problem:

@jsii/kernel.RuntimeError: Error: Template has 1 resources with type AWS::S3::Bucket, but none match as expected.
The 1 closest matches:
MyClassS388392AE1 :: {
  "DeletionPolicy": "Retain",
  "Properties": {
    "BucketName": "my-bucket-name",
!!   Expected type array but received object
    "LifecycleConfiguration": {
      "Rules": [ { ... } ]
    },
    "Tags": [ ... ]
  },
  "Type": "AWS::S3::Bucket",
  "UpdateReplacePolicy": "Retain"
}

Solution

  • Finally I found the correct answer after trying to capture the rules and look into the captured object,

    Here is the correct answer, and now tests passed:

    template.hasResourceProperties("AWS::S3::Bucket",
          Match.objectLike(Map.of(
              "LifecycleConfiguration", Collections.singletonMap(
                  "Rules", Collections.singletonList(
                      Map.of(
                          "ExpirationInDays", 7, "Status", "Enabled"
                      )
                  )
              )
          ))
      );
    

    So, lifecycle configurations mapped value should be in the next form:

    Map<String, List<Map<Object, Object>>>
    

    which means the Rules should be like that:

    Map<Object, Object> rules = Map.of("ExpirationInDays", 7, "Status", "Enabled")