测试 MockRestServiceServer spring-使用多部分请求进行测试
Testing MockRestServiceServer spring-test with multipart request
最近我开始使用 Spring 的 MockRestServiceServer
来验证我在测试中基于 RestTemplate
的请求。
当它用于简单的 get/post 请求时 - 一切都很好,但是,我不知道如何将它用于 POST 多部分请求:
例如,我想测试的工作代码如下所示:
public ResponseEntity<String> doSomething(String someParam, MultipartFile
file, HttpHeaders headers) { //I add headers from request
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename();
}
});
map.add("someParam", someParam);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new
HttpEntity<>(map, headers);
return this.restTemplate.exchange(
getDestinationURI(),
HttpMethod.POST,
requestEntity,
String.class);
}
所以我的问题是如何使用 org.springframework.test.web.client.MockRestServiceServer
指定我的期望?请注意,我不想用 mockito 或其他东西模拟 "exchange" 方法,而是更喜欢使用 MockRestServiceServer
我正在使用 spring-test-4.3.8.RELEASE 版本
代码片段将不胜感激:)
非常感谢
更新:
根据 James 的要求,我添加了无效的测试片段(Spock 测试):
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build()
server.expect(once(), requestTo(getURI()))
.andExpect(method(HttpMethod.POST))
.andExpect(header(HttpHeaders.CONTENT_TYPE, startsWith("multipart/form-data;boundary=")))
.andExpect(content().formData(["someParam" : "SampleSomeParamValue", "file" : ???????] as MultiValueMap))
.andRespond(withSuccess("sample response", MediaType.APPLICATION_JSON))
multipartFile.getBytes() >> "samplefile".getBytes()
multipartFile.getOriginalFilename() >> "sample.txt"
断言请求内容时出现异常。表单数据不同,因为实际的表单数据是在内部使用每个参数的 Content-Disposition、Content-Type、Content-Length 创建的,我不知道如何指定这些预期值
我认为这取决于您想测试表单数据的深度。一种方法,不是 100% 完成,但是 "good enough" 用于单元测试(通常)是做类似的事情:
server.expect(once(), requestTo(getURI()))
.andExpect(method(HttpMethod.POST))
.andExpect(content().string(StringContains.containsString('paramname=Value') ))....
这很丑陋且不完整,但有时很有用。当然,你也可以将表单设置为自己的方法,然后使用模拟来尝试验证预期参数是否全部到位。
Spring 5.3 中的 MockRestServiceServer
中添加了多部分请求预期 - 请参阅:
您可以使用
Parse the body as multipart data and assert it contains exactly the values from the given MultiValueMap. Values may be of type:
- String - form field
- Resource - content from a file
- byte[] - other raw content
Variant of multipartData(MultiValueMap) that does the same but only for a subset of the actual values.
最近我开始使用 Spring 的 MockRestServiceServer
来验证我在测试中基于 RestTemplate
的请求。
当它用于简单的 get/post 请求时 - 一切都很好,但是,我不知道如何将它用于 POST 多部分请求:
例如,我想测试的工作代码如下所示:
public ResponseEntity<String> doSomething(String someParam, MultipartFile
file, HttpHeaders headers) { //I add headers from request
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename();
}
});
map.add("someParam", someParam);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new
HttpEntity<>(map, headers);
return this.restTemplate.exchange(
getDestinationURI(),
HttpMethod.POST,
requestEntity,
String.class);
}
所以我的问题是如何使用 org.springframework.test.web.client.MockRestServiceServer
指定我的期望?请注意,我不想用 mockito 或其他东西模拟 "exchange" 方法,而是更喜欢使用 MockRestServiceServer
我正在使用 spring-test-4.3.8.RELEASE 版本
代码片段将不胜感激:)
非常感谢
更新: 根据 James 的要求,我添加了无效的测试片段(Spock 测试):
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build()
server.expect(once(), requestTo(getURI()))
.andExpect(method(HttpMethod.POST))
.andExpect(header(HttpHeaders.CONTENT_TYPE, startsWith("multipart/form-data;boundary=")))
.andExpect(content().formData(["someParam" : "SampleSomeParamValue", "file" : ???????] as MultiValueMap))
.andRespond(withSuccess("sample response", MediaType.APPLICATION_JSON))
multipartFile.getBytes() >> "samplefile".getBytes()
multipartFile.getOriginalFilename() >> "sample.txt"
断言请求内容时出现异常。表单数据不同,因为实际的表单数据是在内部使用每个参数的 Content-Disposition、Content-Type、Content-Length 创建的,我不知道如何指定这些预期值
我认为这取决于您想测试表单数据的深度。一种方法,不是 100% 完成,但是 "good enough" 用于单元测试(通常)是做类似的事情:
server.expect(once(), requestTo(getURI()))
.andExpect(method(HttpMethod.POST))
.andExpect(content().string(StringContains.containsString('paramname=Value') ))....
这很丑陋且不完整,但有时很有用。当然,你也可以将表单设置为自己的方法,然后使用模拟来尝试验证预期参数是否全部到位。
Spring 5.3 中的 MockRestServiceServer
中添加了多部分请求预期 - 请参阅:
您可以使用
Parse the body as multipart data and assert it contains exactly the values from the given MultiValueMap. Values may be of type:
- String - form field
- Resource - content from a file
- byte[] - other raw content
Variant of multipartData(MultiValueMap) that does the same but only for a subset of the actual values.