0
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只是生成一个静态存根,它总是会返回与我请求相同的响应。

在这种情况下,如何在不重新生成存根的情况下获得随机天气?

4

2 回答 2

3

你不能,那是因为 WireMock 存根在响应端需要一个具体的值。您唯一能做的就是从响应中引用请求,然后请求可以有随机输入。一般来说,您的测试不应依赖于随机响应。

于 2017-09-13T08:30:31.657 回答
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')
    }
}

基类

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()));
    }
}
于 2019-10-31T17:37:46.780 回答