From 9dabc0e14d56d4bcb154dd3960acd558b1cbc12b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 Jul 2019 12:26:58 +0100 Subject: [PATCH] Cleared deferred lines after each test Previously, DeferredLinesWriter would collect MockMvc output from every test that has executed. If a test eventually failed, the output from every test up to including the one that had failed would be output, rather than just the output for the test that has just failed. This commit clears the deferred lines after each test, thereby ensuring that when a failure occurs only the lines from the failing test are output. Fixes gh-17551 --- ...intOnlyOnFailureTestExecutionListener.java | 7 +++--- .../SpringBootMockMvcBuilderCustomizer.java | 4 ++++ ...ebMvcTestPrintDefaultIntegrationTests.java | 3 +++ .../mockmvc/WebMvcTestPrintDefaultRunner.java | 22 +++++++++++++++---- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcPrintOnlyOnFailureTestExecutionListener.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcPrintOnlyOnFailureTestExecutionListener.java index 5ea1423d0e..2150d3f534 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcPrintOnlyOnFailureTestExecutionListener.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/MockMvcPrintOnlyOnFailureTestExecutionListener.java @@ -36,11 +36,12 @@ class MockMvcPrintOnlyOnFailureTestExecutionListener extends AbstractTestExecuti @Override public void afterTestMethod(TestContext testContext) throws Exception { - if (testContext.getTestException() != null) { - DeferredLinesWriter writer = DeferredLinesWriter.get(testContext.getApplicationContext()); - if (writer != null) { + DeferredLinesWriter writer = DeferredLinesWriter.get(testContext.getApplicationContext()); + if (writer != null) { + if (testContext.getTestException() != null) { writer.writeDeferredResult(); } + writer.clear(); } } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizer.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizer.java index a59c6f9c61..89322d62c7 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/SpringBootMockMvcBuilderCustomizer.java @@ -253,6 +253,10 @@ public class SpringBootMockMvcBuilderCustomizer implements MockMvcBuilderCustomi } } + void clear() { + this.lines.clear(); + } + } /** diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultIntegrationTests.java index def6ec2afb..422c79284c 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultIntegrationTests.java @@ -16,8 +16,10 @@ package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc; +import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -38,6 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @WebMvcTest @WithMockUser @AutoConfigureMockMvc +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class WebMvcTestPrintDefaultIntegrationTests { @Autowired diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultRunner.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultRunner.java index e9e7485503..9504337b80 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultRunner.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestPrintDefaultRunner.java @@ -16,6 +16,7 @@ package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc; +import org.assertj.core.matcher.AssertionMatcher; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; @@ -23,8 +24,7 @@ import org.junit.runners.model.Statement; import org.springframework.boot.test.rule.OutputCapture; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; +import static org.assertj.core.api.Assertions.assertThat; /** * Test runner used for {@link WebMvcTestPrintDefaultIntegrationTests}. @@ -43,10 +43,24 @@ public class WebMvcTestPrintDefaultRunner extends SpringJUnit4ClassRunner { statement = new AlwaysPassStatement(statement); OutputCapture outputCapture = new OutputCapture(); if (frameworkMethod.getName().equals("shouldPrint")) { - outputCapture.expect(containsString("HTTP Method")); + outputCapture.expect(new AssertionMatcher() { + + @Override + public void assertion(String actual) throws AssertionError { + assertThat(actual).containsOnlyOnce("HTTP Method"); + } + + }); } else if (frameworkMethod.getName().equals("shouldNotPrint")) { - outputCapture.expect(not(containsString("HTTP Method"))); + outputCapture.expect(new AssertionMatcher() { + + @Override + public void assertion(String actual) throws AssertionError { + assertThat(actual).doesNotContain("HTTP Method"); + } + + }); } else { throw new IllegalStateException("Unexpected test method");