运行CDK测试出现Converting circular structure to JSON错误如何解决
错误原因
这个TypeError: Converting circular structure to JSON报错是AWS CDK v1的@aws-cdk/assert库与Jest 27+版本不兼容导致的:
- Jest 27+版本在执行断言时会默认对传入的对象做JSON序列化处理,用于错误提示和快照比对
- CDK v1的
@aws-cdk/assert返回的栈实例内部存在CloudFormationStackArtifact和CloudAssembly互相引用的循环结构,无法被JSON序列化,因此触发了该报错。
解决方法
方案1:降级Jest到兼容版本
CDK v1的@aws-cdk/assert最高兼容Jest 26版本,直接修改package.json里的Jest相关依赖版本即可:
{ "devDependencies": { "@types/jest": "26.0.24", "jest": "26.6.3", "ts-jest": "26.5.6" } }
修改后重新执行npm install,再运行测试即可正常执行。
方案2:调整断言写法(无需降级依赖)
如果不想降级Jest版本,可以先手动把栈合成CloudFormation模板JSON,再针对模板做断言,避开带循环引用的栈实例:
import * as assert from '@aws-cdk/assert'; import { SynthUtils } from '@aws-cdk/assert'; import * as cdk from '@aws-cdk/core'; import * as RTE from '../lib/rte-stack'; const { countResources, haveResource } = assert; test('Stack creates resources', () => { const app = new cdk.App(); const stack = new RTE.RTEStack(app, 'MyTestStack', { env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION } }); // 先合成模板,拿到无循环引用的JSON对象 const stackTemplate = SynthUtils.toCloudFormation(stack); // 直接针对模板断言 expect(countResources(stackTemplate, 'AWS::IAM::Role', 1)).toBeTruthy(); // 还可以扩展断言校验角色属性 expect(haveResource(stackTemplate, 'AWS::IAM::Role', { RoleName: 'lambdaReadFromASMRole', AssumeRolePolicyDocument: { Statement: [ { Action: 'sts:AssumeRole', Effect: 'Allow', Principal: { Service: 'lambda.amazonaws.com' } } ] } })).toBeTruthy(); });
补充提示
如果后续计划升级CDK版本,CDK v2内置的aws-cdk-lib/assertions断言库已经修复了该兼容问题,原生支持Jest 27+版本。
内容的提问来源于stack exchange,提问作者Oday
相关产品推荐
相关产品推荐

