Pact JVM(JUnit5)如何定义正则匹配的无根数组响应?
问题描述
我正在使用JUnit5进行Pact JVM消费者契约测试,引入的Maven依赖如下:
<dependency> <groupId>au.com.dius.pact.consumer</groupId> <artifactId>junit5</artifactId> <scope>test</scope> </dependency>
需要针对如下无根JSON数组响应创建DslPart匹配模式:
[ "Africa/Abidjan", "Asia/Tokyo", "Africa/Addis_Ababa", ... ]
目前定义了包含固定字符串元素的DslPart,消费者测试可通过:
DslPart expectedZoneResponse = new PactDslJsonArray() .stringValue("Africa/Abidjan") .stringValue("Asia/Tokyo");
Pact契约定义如下:
@Pact(consumer = "Client", provider = "ServiceApi") public RequestResponsePact getTestArray(PactDslWithProvider builder) { return builder .given("ZoneInfo") .uponReceiving("Return all zones.") .path("/zones") .method("GET") .willRespondWith() .status(200) .body(expectedZoneResponse) .toPact(); }
但运行提供者契约测试时失败,报错:
body: $ Expected a List with 2 elements but received 603 elements
希望将DslPart改为使用正则表达式[a-zA-Z]+/[a-zA-Z]+匹配数组元素,而非固定字符串,同时解决数组元素数量不匹配的问题。
解决方案
要解决这个问题,需要同时实现两个目标:
- 用正则表达式匹配数组中每个元素的格式
- 允许数组包含任意数量(或至少指定数量)的元素
修改DslPart定义
使用PactDslJsonArray的minArrayLike或arrayLike方法定义数组的匹配规则,同时用stringMatcher指定元素的正则匹配模板:
DslPart expectedZoneResponse = new PactDslJsonArray() // 匹配至少1个符合规则的元素,可根据业务需求调整min值 .minArrayLike(1, new PactDslJsonRootValue() // 第一个参数是正则表达式,第二个是示例值(用于消费者测试生成模拟响应) .stringMatcher("[a-zA-Z]+/[a-zA-Z_]+", "Africa/Abidjan"));
代码解释
minArrayLike(min, value):指定数组至少包含min个元素,且每个元素都符合value定义的匹配规则。如果业务允许空数组,可改用arrayLike()。stringMatcher(regex, example):定义字符串元素的匹配规则,第一个参数是正则表达式,第二个是示例值。注意原正则[a-zA-Z]+/[a-zA-Z]+无法匹配带下划线的时区(如Africa/Addis_Ababa),所以调整为[a-zA-Z]+/[a-zA-Z_]+以覆盖所有场景。
修改后的完整契约代码
@Pact(consumer = "Client", provider = "ServiceApi") public RequestResponsePact getTestArray(PactDslWithProvider builder) { DslPart expectedZoneResponse = new PactDslJsonArray() .minArrayLike(1, new PactDslJsonRootValue() .stringMatcher("[a-zA-Z]+/[a-zA-Z_]+", "Africa/Abidjan")); return builder .given("ZoneInfo") .uponReceiving("Return all zones.") .path("/zones") .method("GET") .willRespondWith() .status(200) .body(expectedZoneResponse) .toPact(); }
这样修改后,提供者测试时会验证返回的数组中每个元素都符合正则格式,且元素数量不少于1个,不会再因为元素数量不匹配而报错。
内容的提问来源于stack exchange,提问作者MMR
相关产品推荐
相关产品推荐

