如何测试 cdk 堆栈中的引用类型值?

How to test Reference type value in cdk stack?

我正在使用 aws cdk 库创建资源并且能够成功创建资源。现在想测试这个生成的statck。同样,如果它的单个资源能够很好地测试它,但是当堆栈有多个资源时,就不知道如何休息了。

以下是创建资源的代码。

constructor(scope: cdk.Construct, id: string, props: CIAMSQSProps = {} ) {
    super(scope, id);

    const queue = new sqs.Queue(this, id, {
      queueName: props.queueName!,
    });
    
    let ssmParamters = new CreateSSMParamaters(this, id, {
      envName: props.envName!,
      envValue: sqsQueue.queueUrl
    });
}

以下是测试代码,由于堆栈包含引用而失败。

test('Test SSM Parameter', () => {
  const app = new App();
  const sqsStack = new TestSQS(app, 'test-sqs-stack', {
    queueName: 'TestQueue',
    envName: 'TestQueue',
  });

  const template = Template.fromStack(sqsStack);
  template.hasResourceProperties(ResourceTypes.SSM_PARAM_TYPE, "{ Name: 'TestQueue', Value: 'TestQueue', Type: 'String' }");
});

错误如下

Template has 1 resources with type AWS::SSM::Parameter, but none match as expected.
    The closest result is:
      {
        "Type": "AWS::SSM::Parameter",
        "Properties": {
          "Type": "String",
          "Value": {
            "Ref": "testsqsstackEDC1E09E"
          },
          "Name": "TestQueue"
        }
      }
    with the following mismatches:
        Expected type string but received object at /Properties (using objectLike matcher)

有人可以帮我解决这个问题吗?或者有什么方法可以测试资源类型的特定 属性?

我找到了几个选项来测试 属性 引用。我还没有看到关于这个主题的任何记录在案的最佳实践。也许这是因为在大多数情况下,我们不需要测试这些实现细节。

选项 1:Stack 导出源 ConstructResolve 它的 Token 值。

template.hasResourceProperties('AWS::SSM::Parameter', {
  Value: stack.resolve(stack.queue.queueName),
});

选项 2: 同上,但使用 escape hatches 而不是字段导出来获取队列引用。

const childQueue = stack.node.tryFindChild('MyQueue') as sqs.Queue;

template.hasResourceProperties('AWS::SSM::Parameter', {
  Value: stack.resolve(childQueue.queueName),
});

选项 3:在模板中查找队列资源的名称。

const queues = template.findResources('AWS::SQS::Queue');
expect(Object.keys(queues)).toHaveLength(1);
const resolvedQueueName = Object.keys(queues)[0];

template.hasResourceProperties('AWS::SSM::Parameter', {
  Value: { 'Fn::GetAtt': [resolvedQueueName, 'QueueName'],},
});