codecamp

SpringCloud 这个值是什么(consumer(),producer())?

与存根相关的最大挑战之一是它们的可重用性。只有将它们广泛使用,它们才能达到目的。通常使困难的是请求/响应元素的硬编码值。例如日期或ID。想象以下JSON请求

{
    "time" : "2016-10-10 20:10:15",
    "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a",
    "body" : "foo"
}

和JSON响应

{
    "time" : "2016-10-10 21:10:15",
    "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051",
    "body" : "bar"
}

想象一下通过更改系统中的时钟或提供数据提供者的存根实现来设置time字段的适当值(让我们假定此内容是由数据库生成)所需的痛苦。与名为id的字段相同。您将创建UUID生成器的存根实现吗?毫无意义...

因此,作为消费者,您希望发送与任何时间形式或任何UUID匹配的请求。这样,您的系统将像往常一样工作-会生成数据,而您无需存根任何东西。假设在上述JSON的情况下,最重要的部分是body字段。您可以专注于此并为其他字段提供匹配。换句话说,您希望存根像这样工作:

{
    "time" : "SOMETHING THAT MATCHES TIME",
    "id" : "SOMETHING THAT MATCHES UUID",
    "body" : "foo"
}

就响应作为消费者而言,您需要可以操作的具体价值。所以这样的JSON是有效的

{
    "time" : "2016-10-10 21:10:15",
    "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051",
    "body" : "bar"
}

如您在前几节中所看到的,我们根据合同生成测试。因此,从生产者的角度来看,情况似乎大不相同。我们正在解析提供的合同,并且在测试中我们想向您的端点发送真实请求。因此,对于请求的生产者而言,我们无法进行任何形式的匹配。我们需要生产者后端可以使用的具体价值。这样的JSON是有效的:

{
    "time" : "2016-10-10 20:10:15",
    "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a",
    "body" : "foo"
}

另一方面,从合同有效性的角度来看,响应不一定包含timeid的具体值。假设您是在生产者端生成的-再次,您必须进行大量的存根操作以确保始终返回相同的值。因此,从生产者的角度来看,您可能想要以下响应:

{
    "time" : "SOMETHING THAT MATCHES TIME",
    "id" : "SOMETHING THAT MATCHES UUID",
    "body" : "bar"
}

那么,您如何才能一次为消费者提供匹配者,为生产者提供具体价值,反之亦然?在Spring Cloud Contract中,我们允许您提供动态值这意味着通信的双方可能会有所不同。您可以传递值:

通过value方法

value(consumer(...), producer(...))
value(stub(...), test(...))
value(client(...), server(...))

或使用$()方法

$(consumer(...), producer(...))
$(stub(...), test(...))
$(client(...), server(...))

您可以在Contract DSL部分中了解有关此内容的更多信息

调用value()$()会告诉Spring Cloud Contract您将传递动态值。consumer()方法内部,传递应该在使用者方(在生成的存根中)使用的值。producer()方法内部,传递应该在生产方(在生成的测试中)使用的值。

 

如果一侧传递了正则表达式,而另一侧则没有传递,则另一侧将自动生成。

通常,您会将该方法与regex帮助方法一起使用。例如consumer(regex('[0-9]{10}'))

概括起来,上述情况的合同看起来或多或少像这样(时间和UUID的正则表达式已简化,很可能是无效的,但在此示例中,我们希望保持非常简单):

org.springframework.cloud.contract.spec.Contract.make {
				request {
					method 'GET'
					url '/someUrl'
					body([
					    time : value(consumer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')),
					    id: value(consumer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}'))
					    body: "foo"
					])
				}
			response {
				status OK()
				body([
					    time : value(producer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')),
					    id: value([producer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}'))
					    body: "bar"
					])
			}
}
请阅读与JSON相关Groovy文档,以了解如何正确构造请求/响应主体。


SpringCloud 我不想在Groovy中写合同!
SpringCloud API版本控制
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

三、Spring Cloud Netflix

SpringCloud Hystrix超时和Ribbon客户

SpringCloud 重试失败的请求

五、Spring Cloud Stream

六、SpringCloud Binder实现

SpringCloud 重试RabbitMQ Binder

SpringCloud Dead-Letter队列处理

八、Spring Cloud Sleuth

SpringCloud 当前Span

十二、Spring Cloud for Cloud Foundry

十三、Spring Cloud Contract

Spring Cloud Contract验证程序设置

SrpingCloud Gradle项目

十五、Spring Cloud网关

Spring Cloud 配置路由谓词工厂和网关过滤工厂

Spring Cloud TLS / SSL

Spring Cloud网关配置

SpringCloud 故障排除

十八、Spring Cloud GCP

Spring Cloud GCP Spring资源

Spring Cloud Spring JDBC

Spring Cloud Redis的Cloud Memorystore

Spring Cloud 云身份识别代理(IAP)身份验证

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }