Apply global ResultHandlers before ResultMatchers in MockMvc
Prior to this commit, MockMvc applied global ResultMatchers before global ResultHandlers. This lead to unexpected scenarios where a failing matcher would prevent a handler from being applied. One concrete use case is `alwaysDo(print(System.err))` which should print out MockMvc results for debugging purposes. However, if MockMvc is configured with something like `alwaysExpect(content().string("?"))` and the expectation fails, the user will never see the expected debug output to help diagnose the problem. This commit addresses this issue by applying global ResultHandlers before ResultMatchers in MockMvc. Closes gh-27225
This commit is contained in:
parent
e4b9b1fadb
commit
881fa889fc
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -217,12 +217,12 @@ public final class MockMvc {
|
|||
}
|
||||
|
||||
private void applyDefaultResultActions(MvcResult mvcResult) throws Exception {
|
||||
for (ResultMatcher matcher : this.defaultResultMatchers) {
|
||||
matcher.match(mvcResult);
|
||||
}
|
||||
for (ResultHandler handler : this.defaultResultHandlers) {
|
||||
handler.handle(mvcResult);
|
||||
}
|
||||
for (ResultMatcher matcher : this.defaultResultMatchers) {
|
||||
matcher.match(mvcResult);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.servlet.samples.standalone.resulthandlers;
|
||||
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.test.web.servlet.result.PrintingResultHandler;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link PrintingResultHandler}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.3.10
|
||||
* @see PrintingResultHandlerSmokeTests
|
||||
* @see org.springframework.test.web.servlet.result.PrintingResultHandlerTests
|
||||
*/
|
||||
class PrintingResultHandlerIntegrationTests {
|
||||
|
||||
@Test
|
||||
void printMvcResultsToWriter() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
standaloneSetup(new SimpleController())
|
||||
.alwaysDo(print(writer))
|
||||
.build()
|
||||
.perform(get("/").content("Hello Request".getBytes()).characterEncoding("ISO-8859-1"))
|
||||
.andExpect(content().string("Hello Response"));
|
||||
|
||||
assertThat(writer).asString()
|
||||
.contains("Hello Request")
|
||||
.contains("Hello Response")
|
||||
.contains("Headers = [Set-Cookie:\"enigma=42\", Content-Type:\"text/plain;charset=ISO-8859-1\", Content-Length:\"14\"]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void printMvcResultsToWriterWithFailingGlobalResultMatcher() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
try {
|
||||
standaloneSetup(new SimpleController())
|
||||
.alwaysDo(print(writer))
|
||||
.alwaysExpect(content().string("Boom!"))
|
||||
.build()
|
||||
.perform(get("/").content("Hello Request".getBytes()).characterEncoding("ISO-8859-1"));
|
||||
}
|
||||
catch (AssertionError error) {
|
||||
assertThat(error).hasMessageContaining("Boom!");
|
||||
}
|
||||
|
||||
assertThat(writer).asString()
|
||||
.contains("Hello Request")
|
||||
.contains("Hello Response")
|
||||
.contains("Headers = [Set-Cookie:\"enigma=42\", Content-Type:\"text/plain;charset=ISO-8859-1\", Content-Length:\"14\"]");
|
||||
}
|
||||
|
||||
|
||||
@RestController
|
||||
private static class SimpleController {
|
||||
|
||||
@GetMapping("/")
|
||||
String hello(HttpServletResponse response) {
|
||||
response.addCookie(new Cookie("enigma", "42"));
|
||||
return "Hello Response";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue