Skip to content

Support HttpEntity on ContentRequestMatchers.multipartData #36154

@Elvis5566

Description

@Elvis5566

Currently, ContentRequestMatchers.multipartData only supports String, byte[], and Resource.
We use HttpEntity to build multipart requests as follows:

MultiValueMap<String, Object> multipartBody(String filename, String fileContent, MediaType contentType) {
	var resource = new ByteArrayResource(fileContent.getBytes()) {
		@Override
		public String getFilename() {
			return filename;
		}
	};

	HttpHeaders fileHeaders = new HttpHeaders();
	fileHeaders.setContentType(contentType);

	var body = new LinkedMultiValueMap<String, Object>();
	body.add("file", new HttpEntity<>(resource, fileHeaders));

	return body;
}

then we can use this function to post a multipart request:

RestClient restClient = RestClient.create();
        restClient.post()
            .uri(url)
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(multipartBody("foo.txt", "hello, world", MediaType.TEXT_PLAIN))
            .retrieve()
            .toBodilessEntity();

If we use the same function to verify request, we'll run into IllegalArgumentException: Unexpected multipart value: class org.springframework.http.HttpEntity

@Test
void test() {
	var builder = RestClient.builder();
	var mockServiceServer = MockRestServiceServer.bindTo(builder).build();
	
	mockServiceServer.expect(requestTo("http://localhost:8080/foo"))
			.andExpect(content().multipartData(multipartBody("foo.txt", "hello, world", MediaType.TEXT_PLAIN)))
			.andRespond(withSuccess());
	
	builder.build().post().uri("http://localhost:8080/foo")
			.body(multipartBody("foo.txt", "hello, there", MediaType.TEXT_PLAIN))
					.retrieve().toBodilessEntity();

	
	mockServiceServer.verify();
}

Expect:
The test should be able to identify the fileContent is different.
If we can get the actual MultiValueMap instead of the one from MultipartHelper.parse, we can compare two HttpEntities directly and show text file diffs.

I was attempting to fix this issue, but couldn't figure out how to get the "actual" MultiValueMap.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions