Skip to content

Commit d82cb15

Browse files
committed
Ensure both mock files and parts can be provided
Closes gh-26166
1 parent 8c1d06e commit d82cb15

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.test.web.servlet.request;
1818

19+
import java.io.IOException;
1920
import java.net.URI;
2021
import java.util.ArrayList;
2122
import java.util.Collection;
@@ -24,12 +25,14 @@
2425
import javax.servlet.ServletContext;
2526
import javax.servlet.http.Part;
2627

28+
import org.springframework.http.HttpHeaders;
2729
import org.springframework.http.HttpMethod;
2830
import org.springframework.http.MediaType;
2931
import org.springframework.lang.Nullable;
3032
import org.springframework.mock.web.MockHttpServletRequest;
3133
import org.springframework.mock.web.MockMultipartFile;
3234
import org.springframework.mock.web.MockMultipartHttpServletRequest;
35+
import org.springframework.mock.web.MockPart;
3336
import org.springframework.util.Assert;
3437
import org.springframework.util.LinkedMultiValueMap;
3538
import org.springframework.util.MultiValueMap;
@@ -119,7 +122,7 @@ public Object merge(@Nullable Object parent) {
119122
if (parent instanceof MockMultipartHttpServletRequestBuilder) {
120123
MockMultipartHttpServletRequestBuilder parentBuilder = (MockMultipartHttpServletRequestBuilder) parent;
121124
this.files.addAll(parentBuilder.files);
122-
parentBuilder.parts.keySet().stream().forEach(name ->
125+
parentBuilder.parts.keySet().forEach(name ->
123126
this.parts.putIfAbsent(name, parentBuilder.parts.get(name)));
124127
}
125128

@@ -138,9 +141,26 @@ public Object merge(@Nullable Object parent) {
138141
@Override
139142
protected final MockHttpServletRequest createServletRequest(ServletContext servletContext) {
140143
MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(servletContext);
141-
this.files.forEach(request::addFile);
144+
this.files.forEach(file -> request.addPart(toMockPart(file)));
142145
this.parts.values().stream().flatMap(Collection::stream).forEach(request::addPart);
143146
return request;
144147
}
145148

149+
private MockPart toMockPart(MockMultipartFile file) {
150+
byte[] bytes = null;
151+
if (!file.isEmpty()) {
152+
try {
153+
bytes = file.getBytes();
154+
}
155+
catch (IOException ex) {
156+
throw new IllegalStateException("Unexpected IOException", ex);
157+
}
158+
}
159+
MockPart part = new MockPart(file.getName(), file.getOriginalFilename(), bytes);
160+
if (file.getContentType() != null) {
161+
part.getHeaders().set(HttpHeaders.CONTENT_TYPE, file.getContentType());
162+
}
163+
return part;
164+
}
165+
146166
}

spring-test/src/test/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilderTests.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,21 +16,43 @@
1616

1717
package org.springframework.test.web.servlet.request;
1818

19+
import java.nio.charset.StandardCharsets;
20+
21+
import javax.servlet.http.Part;
22+
1923
import org.junit.jupiter.api.Test;
2024

2125
import org.springframework.http.HttpMethod;
2226
import org.springframework.mock.web.MockHttpServletRequest;
27+
import org.springframework.mock.web.MockMultipartFile;
28+
import org.springframework.mock.web.MockPart;
2329
import org.springframework.mock.web.MockServletContext;
30+
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
2431

2532
import static org.assertj.core.api.Assertions.assertThat;
2633

2734
/**
35+
* Unit tests for {@link MockMultipartHttpServletRequestBuilder}.
2836
* @author Rossen Stoyanchev
2937
*/
3038
public class MockMultipartHttpServletRequestBuilderTests {
3139

40+
@Test // gh-26166
41+
void addFilesAndParts() throws Exception {
42+
MockHttpServletRequest mockRequest = new MockMultipartHttpServletRequestBuilder("/upload")
43+
.file(new MockMultipartFile("file", "test.txt", "text/plain", "Test".getBytes(StandardCharsets.UTF_8)))
44+
.part(new MockPart("data", "{\"node\":\"node\"}".getBytes(StandardCharsets.UTF_8)))
45+
.buildRequest(new MockServletContext());
46+
47+
StandardMultipartHttpServletRequest parsedRequest = new StandardMultipartHttpServletRequest(mockRequest);
48+
49+
assertThat(parsedRequest.getParameterMap()).containsOnlyKeys("data");
50+
assertThat(parsedRequest.getFileMap()).containsOnlyKeys("file");
51+
assertThat(parsedRequest.getParts()).extracting(Part::getName).containsExactly("file", "data");
52+
}
53+
3254
@Test
33-
public void test() {
55+
void mergeAndBuild() {
3456
MockHttpServletRequestBuilder parent = new MockHttpServletRequestBuilder(HttpMethod.GET, "/");
3557
parent.characterEncoding("UTF-8");
3658
Object result = new MockMultipartHttpServletRequestBuilder("/fileUpload").merge(parent);

0 commit comments

Comments
 (0)