org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url '/weather'
}
response {
status 200
body([
"weather": value(regex("(SUNNY|WINDY|CLOUDY|RAINY)"))
])
}
我知道Groovy DSL
能够生成随机值,就像上面的代码一样。
但Groovy DSL
只生成一个静态存根,它将始终返回与我请求相同的响应。
在这种情况下如何在不重新生成存根的情况下获得随机天气?
答案 0 :(得分:3)
你不能,那是因为WireMock存根需要响应方面的具体值。您唯一能做的就是从响应中引用请求,然后请求可以随机输入。通常,您的测试不应该依赖于随机响应。
答案 1 :(得分:0)
我知道这是一个老问题,但是我找到了一种workaround
解决方案,可以使用给定请求中的动态值来实现,您可以使用$regex
设置自定义标头,然后用作输出响应。
时髦
request {
method 'GET'
url """/v1/persons/${anyUuid()}"""
headers {
contentType('application/json')
header 'Authorization' : 'Mocked Return Data'
header 'nameMocked' : $(regex('[a-zA-Z0-9]{5, 30}'))
header 'dateMocked' : $(regex('(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/([0-9]{4})'))
header 'typeMocked' : $(regex('CONSUMER|COMMERCIAL'))
}
}
response {
status 200
body(
"""
{
"name": "${fromRequest().header('nameMocked')}",
"date": "${fromRequest().header('dateMocked')}",
"type": "${fromRequest().header('typeMocked')}",
}
"""
)
headers {
contentType('application/json')
}
}
BaseClass
class PersonDto {
private UUID id;
private String name;
private LocalDate date;
private PersonType type;
}
@Slf4j
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = JacksonAutoConfiguration.class)
public abstract class BaseTest {
@Autowired
private ObjectMapper objectMapper;
@Before
public void setup() throws Exception {
YourController yourController = spy(new YourController());
//normal business mocks
doAnswer((Answer<ResponseEntity>) invocation -> {
HttpServletRequest currentRequest = getCurrentRequest();
Map<String, String> map = Collections.list(currentRequest.getHeaderNames()).stream()
.filter(n -> n.endsWith("Mocked"))
.collect(Collectors.toMap(k -> k.replaceFirst("Mocked", ""), currentRequest::getHeader));
return ResponseEntity.ok(objectMapper.convertValue(map, PersonDto.class)); //Convert map to dto
}).when(YourController).getPerson(matches("([a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8})"), eq("Mocked Return Data")); //This should match your request
RestAssuredMockMvc.standaloneSetup(yourController);
}
private HttpServletRequest getCurrentRequest() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
Assert.state(requestAttributes != null, "Could not find current request via RequestContextHolder");
Assert.isInstanceOf(ServletRequestAttributes.class, requestAttributes);
HttpServletRequest servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
Assert.state(servletRequest != null, "Could not find current HttpServletRequest");
return servletRequest;
}
}
消费者示例
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@AutoConfigureStubRunner(workOffline = true, ids = "groupId:artifactId:+:stubs:8083")
@DirtiesContext
public class ConsumerContractAT {
@Test
public void callApiGetShouldReturnDynamicMockedData() {
Response response = RestAssured.given()
.header(HttpHeaders.AUTHORIZATION, "Mocked Return Data")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("nameMocked", "Test")
.header("typeMocked", "CONSUMER")
.header("dobMocked", DateTimeFormatter.ofPattern("dd/MM/yyyy").format(LocalDate.of(2019, 10, 10)))
.when()
.get("/v1/persons/{tokeId}", UUID.randomUUID())
.then()
.statusCode(200)
.extract().response();
assertThat(response.jsonPath().getString("typeMocked")).isEqualTo("CONSUMER");
assertThat(response.jsonPath().getString("name")).isEqualTo("Test");
assertThat(response.jsonPath().getString("dob")).isEqualTo("10/10/2019");
response = RestAssured.given()
.header(HttpHeaders.AUTHORIZATION, "Mocked Return Data")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header("nameMocked", "Test 2")
.header("typeMocked", "COMMERCIAL")
.header("dobMocked", DateTimeFormatter.ofPattern("dd/MM/yyyy").format(LocalDate.now()))
.when()
.get("/v1/persons/{tokeId}", UUID.randomUUID())
.then()
.statusCode(200)
.extract().response();
assertThat(response.jsonPath().getString("typeMocked")).isEqualTo("COMMERCIAL");
assertThat(response.jsonPath().getString("name")).isEqualTo("Test 2");
assertThat(response.jsonPath().getString("dob")).isEqualTo(DateTimeFormatter.ofPattern("dd/MM/yyyy").format(LocalDate.now()));
}
}