我目前很难使用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?