【问题标题】:AWS-CDK How to test props with Fine-grained assertionsAWS-CDK 如何使用细粒度断言测试道具
【发布时间】:2021-04-23 10:56:01
【问题描述】:

如何测试传递给 s3.Bucket 的所有道具? 我想测试传递给 s3.Bucket 的所有道具(无快照)。 测试在 WebsiteConfiguration 上给了我一个错误... 要检查如何在 toHaveResource fn 中编写 prop obj,我使用了 this doc

谁能帮帮我?

import * as cdk from "@aws-cdk/core";
import * as s3 from "@aws-cdk/aws-s3";

export class S3CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, "ReactGitHubActionBucket", {
      versioned: true,
      publicReadAccess: true,
      websiteIndexDocument: "index.html",
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    });
  }
}
import { expect as expectCDK, haveResource } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';
import * as Stacks from '../lib/s3-cdk-stack';

test('First test', () => {
    const app = new cdk.App();

    const stack = new Stacks.S3CdkStack(app, 'S3CdkTestStack');

    expectCDK(stack).to(haveResource("AWS::S3::Bucket",{
      VersioningConfiguration: {
        Status: "Enabled"
      },
      WebsiteConfiguration: {
        IndexDocument: "index.html"
      }
    }))
});
$ jest
 FAIL  test/stacks.test.ts
  ✕ First test (68 ms)

  ● First test

    None of 1 resources matches resource 'AWS::S3::Bucket' with {
      "$objectLike": {
        "VersioningConfiguration": {
          "Status": "Enabled"
        },
        "WebsiteConfiguration": {
          "IndexDocument": "index.html"
        }
      }
    }.
    - Field WebsiteConfiguration missing in:
        {
          "Type": "AWS::S3::Bucket",
          "Properties": {
            "VersioningConfiguration": {
              "Status": "Enabled"
            }
          },
          "UpdateReplacePolicy": "Retain",
          "DeletionPolicy": "Retain"
        }

【问题讨论】:

  • 您使用的是哪个 cdk 版本?
  • 版本 1.99.0 @nirvana124

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


【解决方案1】:

自从您写下您的问题后,它可能已经更新,但从 CDK 1.113.0 开始,以下示例适用于我。

请注意,我的导入与您的略有不同,并且我使用了 .toHaveResource() 而不是 .to(haveResource())

// CDK version: 1.113.0
import '@aws-cdk/assert/jest';
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';

// Included for completeness, but you'd import this:
class S3CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'ReactGitHubActionBucket', {
      versioned: true,
      publicReadAccess: true,
      websiteIndexDocument: 'index.html',
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    });
  }
}

// This test should pass:
test('Test complete S3 bucket configuration', () => {
  const app = new cdk.App();
  const stack = new S3CdkStack(app, 'S3CdkTestStack');

  //            ↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  expect(stack).toHaveResource('AWS::S3::Bucket', {
    VersioningConfiguration: {
      Status: 'Enabled',
    },
    WebsiteConfiguration: {
      IndexDocument: 'index.html',
    },
  });
});

额外提示:.toHaveResourceLike()

.toHaveResource() 在您检查的资源属性值很简单(即标量值,如字符串或数字)时效果很好,但如果它更复杂,您应该查看.toHaveResourceLike(),不幸的是不是非常有据可查 (link to the v1.113.0 source)。

例如,您通过上面的 S3CdkStack() 类创建的 CloudFormation 模板包含具有以下 Description 属性的 Lambda 函数:

{
  "Resources": {
    "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Description": {
          "Fn::Join": [
            "",
            [
              "Lambda function for auto-deleting objects in ",
              {
                "Ref": "ReactGitHubActionBucket1CE57800"
              },
              " S3 bucket."
            ]
          ]
        }
      }
    }
  }
}

使用.toHaveResource() 测试该描述中是否存在“自动删除”(仅作为说明性示例)将需要包含整个描述对象,该对象很脆弱并且包含看起来像哈希的内容...

在这种情况下,最好使用.toHaveResourceLike() 并仅检查您有兴趣测试的对象部分:

test('Test a subset of the Lambda description', () => {
  const app = new cdk.App();
  const stack = new S3CdkStack(app, 'S3CdkTestStack');

  //                          ↓↓↓↓
  expect(stack).toHaveResourceLike('AWS::Lambda::Function', {
    // Only need to include the subset of
    // the value object you're testing:
    Description: {
      'Fn::Join': [
        '',
        ['Lambda function for auto-deleting objects in '],
      ],
    },
  });
});

【讨论】:

    猜你喜欢
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    相关资源
    最近更新 更多