简体   繁体   English

断言具有 CDK 自动生成名称的特定 S3 存储桶的存在

[英]Assert for the existence of a specific S3 bucket with a CDK autogenerated name

Imagine a toy CDK stack with one S3 bucket:想象一下带有一个 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');
     }
    }

Importantly, we have specified only the id of the resource and not its name (ie, BucketName ).重要的是,我们只指定了资源的id而不是它的名称(即BucketName )。 It's good practice not to rely on a specific name since they have to be unique, so even the CDK docs recommend letting CDK autogenerate the name .最好不要依赖特定名称,因为它们必须是唯一的,因此即使是 CDK 文档也建议让 CDK 自动生成名称 This is perfectly fine - but how do you now test for the existence of this specific bucket in a Jest test case?这很好——但是您现在如何在 Jest 测试用例中测试这个特定桶的存在?

For instance, if we had:例如,如果我们有:

    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!
            });
        });
    });

The template will have something like:该模板将具有以下内容:

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

A potential solution could check using a regex for "MySpecificBucket*" to exists, but I guess there are no guarantees what kind of a name CDK will autogenerate.一个潜在的解决方案可以使用正则表达式检查“MySpecificBucket*”是否存在,但我想不能保证 CDK 会自动生成哪种名称。 Also, it's not satisfactory to just count the number of S3 buckets via resourceCountIs because I want to assert the existence of a specific bucket whose name I specifically don't care about.此外,仅通过resourceCountIs计算 S3 存储桶的数量并不令人满意,因为我想断言存在一个我特别不关心其名称的特定存储桶。 If I just have the id specified, how can I write a test with these requirements (or should I somehow change my thinking)?如果我只指定了id ,我该如何编写具有这些要求的测试(或者我应该以某种方式改变我的想法)?

Here are several options to assert the presence of a resource with a specific ID.这里有几个选项可以断言具有特定 ID 的资源的存在。

Assert with escape hatch syntax:使用转义舱口语法断言:

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);

Assert with the CDK testing construct and regex:使用 CDK 测试结构和正则表达式断言:

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

If you have many such assertions to make, consider snapshot testing.如果您要做出许多这样的断言,请考虑快照测试。 This is what the CDK itself does.这就是 CDK 本身所做的。 See the @aws-cdk/integ-tests-alpha module.请参阅@aws-cdk/integ-tests-alpha模块。

FWIW, they also intentionally write a test that fails, grab the correct identifier from the output, and fix the test in the CDK TypeScript workshop . FWIW,他们还故意编写了一个失败的测试,从 output 中获取了正确的标识符,并在CDK TypeScript workshop中修复了测试。

Specifically, they do:具体来说,他们这样做:

$ npm run test

> cdk-workshop@0.1.0 test /home/aws-cdk-intro-workshop
> jest

 FAIL  test/hitcounter.test.ts
  ✓ DynamoDB Table Created (184ms)
  ✕ Lambda Has Environment Variables (53ms)

  ● Lambda Has Environment Variables

    expect(received).toEqual(expected) // deep equality

    - Expected  - 2
    + Received  + 2

      Object {
        "Variables": Object {
          "DOWNSTREAM_FUNCTION_NAME": Object {
    -       "Ref": "TestFunctionXXXXX",
    +       "Ref": "TestFunction22AD90FC",
          },
          "HITS_TABLE_NAME": Object {
    -       "Ref": "MyTestConstructHitsXXXXX",
    +       "Ref": "MyTestConstructHits24A357F0",
          },
        },
      }

      37 |     Environment: envCapture,
      38 |   });
    > 39 |   expect(envCapture.asObject()).toEqual(
         |                                 ^
      40 |     {
      41 |       Variables: {
      42 |         DOWNSTREAM_FUNCTION_NAME: {

      at Object.<anonymous> (test/hitcounter.test.ts:39:33)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        3.971 s, estimated 4 s
Ran all test suites.

I suppose they wouldn't advocate for this approach if there was a better alternative.我想如果有更好的选择,他们不会提倡这种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 GitHub 部署到 S3 存储桶的 CDK 管道 - CDK pipeline to deploy to S3 bucket from GitHub 使用带有源代码的现有 S3 存储桶通过 AWS CDK 进行部署 - Using existing S3 bucket with source code to deploy with AWS CDK 使 Quicksight 资源依赖于 AWS CDK 中的 s3 存储桶创建 - Make Quicksight resource depend on an s3 bucket creation in AWS CDK S3:无效的存储桶名称 - 存储桶名称必须与正则表达式匹配 - S3: Invalid bucket name - Bucket name must match the regex AWS s3 试图修复错误 s3.meta.client.head_bucket(Bucket=bucket_name) - AWS s3 trying to fix error s3.meta.client.head_bucket(Bucket=bucket_name) 有没有办法使用 aws s3 ls cli 将 S3 存储桶名称添加到存储桶的递归列表中? - Is there a way to add the S3 bucket name to the recursive list of a bucket using aws s3 ls cli? 仅授予特定用户对 S3 存储桶的访问权限,无公共访问权限 - Grant access to an S3 bucket for a specific user only, no public access 将我的 Amazon S3 存储桶访问权限限制在特定国家/地区 - Restrict my Amazon S3 bucket access to specific Country S3 Bucket Key 名称是否需要文件扩展名? - Does S3 Bucket Key name require file extension? AWS Lambda 尝试将文件从 S3 存储桶复制到另一个 S3 存储桶时出现无效存储桶名称错误 - Invalid bucket name error when AWS Lambda tries to copy files from an S3 bucket to another S3 bucket
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM