RestDocs的Spring Cloud Contracts:自定义匹配器

时间:2018-11-06 10:56:55

标签: rest-assured spring-cloud-contract spring-restdocs

我目前很难使用rest-assured从restdocs测试生成有意义的合同。问题是我找不到生成正则表达式匹配器的方法,似乎只生成了byEquality匹配器。 The documentation根本没有提到放心,因此它的功能集可能与模拟mvc尚不相同。是否可以使用rest-assured和自定义匹配器从restdocs生成合同?

我当前的设置如下

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(value = [RestDocumentationExtension::class, SpringExtension::class])
class MasterplanResourceTest(
    @LocalServerPort val port: Int,
    @Autowired val mapper: ObjectMapper
) {

    private val defaultDocument = document("{method_name}", SpringCloudContractRestDocs.dslContract())
    lateinit var spec: RequestSpecification

    @BeforeEach
    internal fun setUp(restDocumentationContextProvider: RestDocumentationContextProvider) {
        RestAssured.port = port
        spec = RequestSpecBuilder()
            .setConfig(
                RestAssuredConfig.config()
                    .objectMapperConfig(
                        ObjectMapperConfig.objectMapperConfig()
                            .jackson2ObjectMapperFactory { _, _ -> mapper }
                    )
            )
            .addHeader("X-Forwarded-Host", "gateway-host")
            .addFilter(
                documentationConfiguration(restDocumentationContextProvider)
                    .operationPreprocessors()
                    .withResponseDefaults(
                        Preprocessors.removeMatchingHeaders("Date")
                    )
            )
            .addFilter(defaultDocument)
            .addFilter(ResponseLoggingFilter())
            .log(LogDetail.ALL)
            .build()
    }

    @Test
    fun createMasterplan() {
        RestAssured.given(spec)
            .contentType(ContentType.JSON)
            .filter(
                defaultDocument.document(
                    links(
                        linkWithRel("self").description("Link to the generated masterplan")
                    ),
                    requestFields(
                        fieldWithPath("file.file_uid").description("File id used to retrieve file information from upload service"),
                        fieldWithPath("description").description("Description")
                            .attributes(Attributes.key("contract.jsonPaths").value("link"))
                    ),
                    responseFields(
                        fieldWithPath("created_by").description("File name"),
                        fieldWithPath("description").description("Description"),
                        fieldWithPath("file").description("File linked to the masterplan"),
                        fieldWithPath("file.file_uid").description("File unique identifier"),
                        fieldWithPath("file.name").description("File name"),
                        fieldWithPath("file.size").description("File size in bytes"),
                        fieldWithPath("file.href").description("File download link"),
                        fieldWithPath("file.uploaded_by").description("File uploader")
                    ).and(
                        subsectionWithPath("_links").ignored()
                    )
                )
            )
            .body("""{"description":"something","file":{"file_uid":"fileUid"}}""")
            .`when`().post("/projects/project/masterplans")
            .then().assertThat()
            .statusCode(`is`(200))
            .body("description", equalTo("something"))
            .body("created_by", equalTo("me"))
            .body("file.size", equalTo(100))
            .body("file.file_uid", equalTo("fileUid"))
            .body("file.name", equalTo("filename"))
            .body("file.href", matchesPattern(".*/projects/project/masterplans/\\d+/files/fileUid$"))
            .body("file.uploaded_by", equalTo("someone"))
            .body("_links.self.href", matchesPattern(".*/projects/project/masterplans/\\d+"))
    }

此代码生成以下合同:

import org.springframework.cloud.contract.spec.Contract

Contract.make {
    request {
        method 'POST'
        url '/projects/project/masterplans'
        body('''
            {"description":"something","file":{"file_uid":"fileUid"}}
        ''')
        headers {
            header('''X-Forwarded-Host''', '''gateway-host''')
            header('''Content-Type''', '''application/json; charset=UTF-8''')
        }
    }
    response {
        status 200
        body('''
        {"created_by":"me","description":"something","file":{"file_uid":"fileUid","name":"filename","size":100,"href":"http://gateway-host/projects/project/masterplans/102/files/fileUid","uploaded_by":"someone"},"_links":{"self":{"href":"http://gateway-host/projects/project/masterplans/102"}}}
        ''')
        headers {
            header('''Content-Type''', '''application/hal+json;charset=UTF-8''')
            header('''Transfer-Encoding''', '''chunked''')
        }
    }
}

现在,我想将matchesPattern(来自jcabi库的自定义hamcrest匹配器)反映到合同本身中,所以用"_links":{"self":{"href":".*/projects/project/masterplans/\d+"代替"_links":{"self":{"href":"http://gateway-host/projects/project/masterplans/102" 。可以放心使用还是我必须切换到嘲笑mvcvc?

0 个答案:

没有答案