You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Cloud Contract中复用合约里的复杂数据结构?

Spring Cloud Contract 复用复杂字段的最佳方法

针对你提到的重复定义amount这类复杂数据结构的问题,有两种实用方案可以实现复用:

方案一:提取公共闭包到共享脚本

这是最轻量化的方式,适合简单的结构复用:

  1. 在合约目录(通常是src/test/resources/contracts)下创建共享定义文件CommonDefinitions.groovy:
def amount = {
    [
        value: $(consumer(regex("\\d*\\.\\d+|\\d+")), producer(1234.435)),
        currency: $(consumer(regex("[A-Z]{3}")), producer("GBP"))
    ]
}
  1. 在合约脚本中导入共享文件并调用闭包:
import org.springframework.cloud.contract.spec.Contract

// 导入共享定义脚本
evaluate(new File("src/test/resources/contracts/CommonDefinitions.groovy"))

Contract.make {
    request {
        method(POST())
        url("transfer")
        headers {
            contentType(applicationJson())
        }
        body([
                target_account_id: "",
                source_account_id: "",
                amount: amount(),
        ])
    }
    response {
        status(OK())
        headers {
            contentType(applicationJson())
        }
        body([
                id: "",
                status: "",
        ])
    }
}

若合约文件在子目录,需调整evaluate中的文件路径以确保能正确找到共享脚本。

方案二:使用Groovy基类脚本

如果需要复用多个公共方法或更复杂逻辑,推荐用基类方式:

  1. 创建基类脚本BaseContract.groovy放在合约目录下:
import org.springframework.cloud.contract.spec.Contract

abstract class BaseContract extends Contract {
    def amount() {
        [
            value: $(consumer(regex("\\d*\\.\\d+|\\d+")), producer(1234.435)),
            currency: $(consumer(regex("[A-Z]{3}")), producer("GBP"))
        ]
    }
}
  1. 让合约脚本继承基类并调用方法:
import org.springframework.cloud.contract.spec.Contract

class TransferContract extends BaseContract {
    def make() {
        request {
            method(POST())
            url("transfer")
            headers {
                contentType(applicationJson())
            }
            body([
                    target_account_id: "",
                    source_account_id: "",
                    amount: amount(),
            ])
        }
        response {
            status(OK())
            headers {
                contentType(applicationJson())
            }
            body([
                    id: "",
                    status: "",
            ])
        }
    }
}

两种方案都能有效减少重复代码,保持合约脚本简洁,可根据复用需求复杂度选择。

内容的提问来源于stack exchange,提问作者SiliconMind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:45:31