55
55
import org .springframework .test .context .junit .jupiter .web .SpringJUnitWebConfig ;
56
56
import org .springframework .test .web .Person ;
57
57
import org .springframework .test .web .servlet .ResultMatcher ;
58
+ import org .springframework .test .web .servlet .assertj .MockMvcTester .MockMultipartMvcRequestBuilder ;
58
59
import org .springframework .test .web .servlet .assertj .MockMvcTester .MockMvcRequestBuilder ;
59
60
import org .springframework .ui .Model ;
60
61
import org .springframework .validation .Errors ;
@@ -105,6 +106,9 @@ public class MockMvcTesterIntegrationTests {
105
106
@ Nested
106
107
class PerformTests {
107
108
109
+ private final MockMultipartFile file = new MockMultipartFile ("file" , "content.txt" , null ,
110
+ "value" .getBytes (StandardCharsets .UTF_8 ));
111
+
108
112
@ Test
109
113
void syncRequestWithDefaultExchange () {
110
114
assertThat (mvc .get ().uri ("/greet" )).hasStatusOk ();
@@ -116,6 +120,13 @@ void asyncRequestWithDefaultExchange() {
116
120
.hasBodyTextEqualTo ("name=Joe&someBoolean=true" );
117
121
}
118
122
123
+ @ Test
124
+ void asyncMultipartRequestWithDefaultExchange () {
125
+ assertThat (mvc .post ().uri ("/multipart-streaming" ).multipart ()
126
+ .file (this .file ).param ("timeToWait" , "100" ))
127
+ .hasStatusOk ().hasBodyTextEqualTo ("name=Joe&file=content.txt" );
128
+ }
129
+
119
130
@ Test
120
131
void syncRequestWithExplicitExchange () {
121
132
assertThat (mvc .get ().uri ("/greet" ).exchange ()).hasStatusOk ();
@@ -127,6 +138,13 @@ void asyncRequestWithExplicitExchange() {
127
138
.hasStatusOk ().hasBodyTextEqualTo ("name=Joe&someBoolean=true" );
128
139
}
129
140
141
+ @ Test
142
+ void asyncMultipartRequestWitExplicitExchange () {
143
+ assertThat (mvc .post ().uri ("/multipart-streaming" ).multipart ()
144
+ .file (this .file ).param ("timeToWait" , "100" ).exchange ())
145
+ .hasStatusOk ().hasBodyTextEqualTo ("name=Joe&file=content.txt" );
146
+ }
147
+
130
148
@ Test
131
149
void syncRequestWithExplicitExchangeIgnoresDuration () {
132
150
Duration timeToWait = mock (Duration .class );
@@ -140,28 +158,43 @@ void asyncRequestWithExplicitExchangeAndEnoughTimeToWait() {
140
158
.hasStatusOk ().hasBodyTextEqualTo ("name=Joe&someBoolean=true" );
141
159
}
142
160
161
+ @ Test
162
+ void asyncMultipartRequestWithExplicitExchangeAndEnoughTimeToWait () {
163
+ assertThat (mvc .post ().uri ("/multipart-streaming" ).multipart ()
164
+ .file (this .file ).param ("timeToWait" , "100" ).exchange (Duration .ofMillis (200 )))
165
+ .hasStatusOk ().hasBodyTextEqualTo ("name=Joe&file=content.txt" );
166
+ }
167
+
143
168
@ Test
144
169
void asyncRequestWithExplicitExchangeAndNotEnoughTimeToWait () {
145
170
MockMvcRequestBuilder builder = mvc .get ().uri ("/streaming" ).param ("timeToWait" , "500" );
146
171
assertThatIllegalStateException ()
147
172
.isThrownBy (() -> builder .exchange (Duration .ofMillis (100 )))
148
173
.withMessageContaining ("was not set during the specified timeToWait=100" );
149
174
}
175
+
176
+ @ Test
177
+ void asyncMultipartRequestWithExplicitExchangeAndNotEnoughTimeToWait () {
178
+ MockMultipartMvcRequestBuilder builder = mvc .post ().uri ("/multipart-streaming" ).multipart ()
179
+ .file (this .file ).param ("timeToWait" , "500" );
180
+ assertThatIllegalStateException ()
181
+ .isThrownBy (() -> builder .exchange (Duration .ofMillis (100 )))
182
+ .withMessageContaining ("was not set during the specified timeToWait=100" );
183
+ }
150
184
}
151
185
152
186
@ Nested
153
187
class RequestTests {
154
188
155
189
@ Test
156
190
void hasAsyncStartedTrue () {
157
- // Need #perform as the regular exchange waits for async completion automatically
158
- assertThat (mvc .perform (mvc .get ().uri ("/callable" ).accept (MediaType .APPLICATION_JSON )))
191
+ assertThat (mvc .get ().uri ("/callable" ).accept (MediaType .APPLICATION_JSON ).asyncExchange ())
159
192
.request ().hasAsyncStarted (true );
160
193
}
161
194
162
195
@ Test
163
196
void hasAsyncStartedFalse () {
164
- assertThat (mvc .get ().uri ("/greet" )).request ().hasAsyncStarted (false );
197
+ assertThat (mvc .get ().uri ("/greet" ). asyncExchange () ).request ().hasAsyncStarted (false );
165
198
}
166
199
167
200
@ Test
@@ -325,8 +358,7 @@ class BodyTests {
325
358
326
359
@ Test
327
360
void asyncResult () {
328
- // Need #perform as the regular exchange waits for async completion automatically
329
- MvcTestResult result = mvc .perform (mvc .get ().uri ("/callable" ).accept (MediaType .APPLICATION_JSON ));
361
+ MvcTestResult result = mvc .get ().uri ("/callable" ).accept (MediaType .APPLICATION_JSON ).asyncExchange ();
330
362
assertThat (result .getMvcResult ().getAsyncResult ())
331
363
.asInstanceOf (InstanceOfAssertFactories .map (String .class , Object .class ))
332
364
.containsOnly (entry ("key" , "value" ));
@@ -694,9 +726,24 @@ ModelAndView part(@RequestPart Part part, @RequestPart Map<String, String> json)
694
726
}
695
727
696
728
@ PutMapping ("/multipart-put" )
697
- public ModelAndView multiPartViaHttpPut (@ RequestParam MultipartFile file ) {
729
+ ModelAndView multiPartViaHttpPut (@ RequestParam MultipartFile file ) {
698
730
return new ModelAndView ("index" , Map .of ("name" , file .getName ()));
699
731
}
732
+
733
+ @ PostMapping ("/multipart-streaming" )
734
+ StreamingResponseBody streaming (@ RequestParam MultipartFile file , @ RequestParam long timeToWait ) {
735
+ return out -> {
736
+ PrintStream stream = new PrintStream (out , true , StandardCharsets .UTF_8 );
737
+ stream .print ("name=Joe" );
738
+ try {
739
+ Thread .sleep (timeToWait );
740
+ stream .print ("&file=" + file .getOriginalFilename ());
741
+ }
742
+ catch (InterruptedException e ) {
743
+ /* no-op */
744
+ }
745
+ };
746
+ }
700
747
}
701
748
702
749
@ Controller
0 commit comments