diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java index 20725cb17814..95355e00f789 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java @@ -17,6 +17,7 @@ package org.springframework.test.web.servlet.assertj; import java.io.BufferedReader; +import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; @@ -37,6 +38,7 @@ import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultHandler; import org.springframework.test.web.servlet.ResultMatcher; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.web.servlet.ModelAndView; /** @@ -136,6 +138,26 @@ public ObjectAssert asyncResult() { return Assertions.assertThat(getMvcResult().getAsyncResult()).as("Async result"); } + /** + * Print {@link MvcResult} details to {@code System.out}. + *

You must call it before calling the assertion otherwise it is ignored + * as the failing assertion breaks the chained call by throwing an + * AssertionError. + */ + public MvcTestResultAssert debug() { + return debug(System.out); + } + + /** + * Print {@link MvcResult} details to the supplied {@link OutputStream}. + *

You must call it before calling the assertion otherwise it is ignored + * as the failing assertion breaks the chained call by throwing an + * AssertionError. + */ + public MvcTestResultAssert debug(OutputStream stream) { + return apply(MockMvcResultHandlers.print(stream)); + } + /** * Verify that the request has failed. */ diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/MockMvcTesterIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/MockMvcTesterIntegrationTests.java index 2eafba04ba5d..ae1b2c992872 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/MockMvcTesterIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/MockMvcTesterIntegrationTests.java @@ -16,6 +16,9 @@ package org.springframework.test.web.servlet.assertj; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -30,6 +33,8 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import jakarta.validation.constraints.Size; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -275,6 +280,44 @@ void isInvokedOn() { } } + @Nested + class DebugTests { + + private final PrintStream standardOut = System.out; + + private final ByteArrayOutputStream capturedOut = new ByteArrayOutputStream(); + + @BeforeEach + public void setUp() { + System.setOut(new PrintStream(capturedOut)); + } + + @AfterEach + public void tearDown() { + System.setOut(standardOut); + } + + @Test + void debugUsesSystemOutByDefault() { + assertThat(mvc.get().uri("/greet")).debug().hasStatusOk(); + assertThat(capturedOut()).contains("MockHttpServletRequest:", "MockHttpServletResponse:"); + } + + @Test + void debugCanPrintToCustomOutputStream() { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + assertThat(mvc.get().uri("/greet")).debug(out).hasStatusOk(); + assertThat(out.toString(StandardCharsets.UTF_8)) + .contains("MockHttpServletRequest:", "MockHttpServletResponse:"); + assertThat(capturedOut()).isEmpty(); + } + + private String capturedOut() { + return this.capturedOut.toString(StandardCharsets.UTF_8); + } + + } + @Nested class ExceptionTests {