【问题标题】:Assert for the existence of a specific S3 bucket with a CDK autogenerated name断言具有 CDK 自动生成名称的特定 S3 存储桶的存在
【发布时间】:2023-01-23 16:20:45
【问题描述】:

想象一下带有一个 S3 存储桶的玩具 CDK 堆栈:

    import * as cdk from '@aws-cdk/core';
    import * as s3 from '@aws-cdk/aws-s3';
    
    export class BucketStack extends cdk.Stack {
     constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
       super(scope, id, props);
    
       new s3.Bucket(this, 'MySpecificBucket');
     }
    }

重要的是,我们只指定了资源的 id 而不是它的名称(即 BucketName)。最好不要依赖特定名称,因为它们必须是唯一的,因此即使是 CDK 文档也建议让 CDK autogenerate the name。这很好——但是您现在如何在 Jest 测试用例中测试这个特定桶的存在?

例如,如果我们有:

    import * as cdk from 'aws-cdk-lib';
    import { Template } from 'aws-cdk-lib/assertions';
    import { BucketStack  } from '../lib/bucket-stack';
    
    let template: Template;
    
    beforeAll(async () => {
        const app = new cdk.App();
        // WHEN
        const stack = new BucketStack(app, 'MyTestStack', {});
        // THEN
        template = Template.fromStack(stack);
    });
    
    describe("My test suite", () => {
        test("S3 bucket exists", () => {
            template.hasResourceProperties("AWS::S3::Bucket", {
                BucketName: "wont-work" // this is autogenerated!
            });
        });
    });

该模板将具有以下内容:

    {
       MySpecificBucketF68F3FF0: {
         Type: 'AWS::S3::Bucket',
         UpdateReplacePolicy: 'Retain',
         DeletionPolicy: 'Retain'
       }
    }

一个潜在的解决方案可以使用正则表达式检查“MySpecificBucket*”是否存在,但我想不能保证 CDK 会自动生成哪种名称。此外,仅通过 resourceCountIs 计算 S3 存储桶的数量并不令人满意,因为我想断言存在一个我特别不关心其名称的特定存储桶。如果我只指定了id,我该如何编写具有这些要求的测试(或者我应该以某种方式改变我的想法)?

【问题讨论】:

    标签: amazon-web-services amazon-s3 aws-cdk


    【解决方案1】:

    这里有几个选项可以断言具有特定 ID 的资源的存在。

    使用 escape hatch 语法断言:

    const bucket = stack.node.tryFindChild("MySpecificBucket");
    
    expect(bucket).toBeDefined();
    expect(bucket instanceof s3.Bucket).toBe(true);
    expect(bucket?.node.defaultChild instanceof s3.CfnBucket).toBe(true);
    

    使用 CDK 测试结构和正则表达式断言:

    expect(
      Object.keys(template.findResources("AWS::S3::Bucket")).find((key) =>
        key.match(/^MySpecificBucket[A-F0-9]{8}$/)
      )
    ).toBeDefined();
    

    【讨论】:

    • 对于最后一个示例,是否可以保证 CDK 会自动生成与该正则表达式匹配的名称?通过查看示例,它目前似乎是这样工作的,但它是否承诺会一直这样工作?
    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多