From d11d5ceb290eed02f951c1b667ef65e921671a7d Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 30 May 2019 21:51:07 -0700 Subject: [PATCH] Split up JUnit 5 OutputCapture class Split the JUnit 5 `OutputCapture` class into separate `OutputExtension` and `CapturedOutput` classes. The JUnit 5 callback methods are now contained only in the `OutputExtension` class so no longer pollute the public API that users will interact with. The `CapturedOutput` class has also been updated to capture System.err and System.out separately to allow distinct assertions if required. Closes gh-17029 --- ...usMetricsExportAutoConfigurationTests.java | 5 +- ...RestTemplateMetricsConfigurationTests.java | 5 +- .../WebClientMetricsConfigurationTests.java | 5 +- .../WebFluxMetricsAutoConfigurationTests.java | 5 +- .../WebMvcMetricsAutoConfigurationTests.java | 5 +- ...nagementContextAutoConfigurationTests.java | 5 +- .../actuate/endpoint/EndpointIdTests.java | 5 +- .../FreeMarkerAutoConfigurationTests.java | 5 +- .../InfluxDbAutoConfigurationTests.java | 5 +- ...utoConfigurationServletContainerTests.java | 7 +- .../LiquibaseAutoConfigurationTests.java | 7 +- ...nEvaluationReportLoggingListenerTests.java | 5 +- .../quartz/QuartzAutoConfigurationTests.java | 5 +- .../SecurityAutoConfigurationTests.java | 5 +- ...ConfigurationEarlyInitializationTests.java | 5 +- ...rDetailsServiceAutoConfigurationTests.java | 5 +- .../TaskExecutionAutoConfigurationTests.java | 5 +- ...ymeleafReactiveAutoConfigurationTests.java | 5 +- ...orWebExceptionHandlerIntegrationTests.java | 5 +- .../error/ErrorMvcAutoConfigurationTests.java | 5 +- .../boot/test/extension/CapturedOutput.java | 314 ++++++++++++++++++ .../boot/test/extension/OutputCapture.java | 210 ------------ .../boot/test/extension/OutputExtension.java | 118 +++++++ .../test/extension/CapturedOutputTests.java | 180 ++++++++++ ...va => OutputExtensionExtendWithTests.java} | 12 +- ...utputExtensionRegisterExtensionTests.java} | 6 +- .../springframework/boot/ansi/AnsiOutput.java | 14 +- .../sample/activemq/SampleActiveMqTests.java | 5 +- .../SampleActuatorLog4J2ApplicationTests.java | 5 +- .../sample/aop/SampleAopApplicationTests.java | 5 +- .../batch/SampleBatchApplicationTests.java | 5 +- .../SampleCassandraApplicationTests.java | 7 +- .../SampleCouchbaseApplicationTests.java | 5 +- .../SampleElasticsearchApplicationTests.java | 5 +- .../data/ldap/SampleLdapApplicationTests.java | 7 +- .../mongo/SampleMongoApplicationTests.java | 7 +- .../neo4j/SampleNeo4jApplicationTests.java | 5 +- .../redis/SampleRedisApplicationTests.java | 5 +- .../data/solr/SampleSolrApplicationTests.java | 5 +- .../jooq/SampleJooqApplicationTests.java | 5 +- .../SampleAtomikosApplicationTests.java | 5 +- .../SampleBitronixApplicationTests.java | 5 +- .../SampleLiquibaseApplicationTests.java | 5 +- .../SampleLogbackApplicationTests.java | 5 +- .../SampleProfileApplicationTests.java | 5 +- .../quartz/SampleQuartzApplicationTests.java | 5 +- .../simple/SampleSimpleApplicationTests.java | 5 +- .../webservices/SampleWsApplicationTests.java | 5 +- .../xml/SampleSpringXmlApplicationTests.java | 5 +- 49 files changed, 761 insertions(+), 313 deletions(-) create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/CapturedOutput.java delete mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputCapture.java create mode 100644 spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputExtension.java create mode 100644 spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/CapturedOutputTests.java rename spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/{OutputCaptureExtendWithTests.java => OutputExtensionExtendWithTests.java} (78%) rename spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/{OutputCaptureRegisterExtensionTests.java => OutputExtensionRegisterExtensionTests.java} (88%) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java index 4d11ff71dfe..cfae6cd3338 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java @@ -29,7 +29,8 @@ import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScra import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -45,7 +46,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class PrometheusMetricsExportAutoConfigurationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java index 57e0fd6ef3d..1957439e5f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java @@ -29,7 +29,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpStatus; import org.springframework.test.web.client.MockRestServiceServer; @@ -54,7 +55,7 @@ public class RestTemplateMetricsConfigurationTests { HttpClientMetricsAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void restTemplateCreatedWithBuilderIsInstrumented() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/WebClientMetricsConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/WebClientMetricsConfigurationTests.java index a3a775039a4..074bf634127 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/WebClientMetricsConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/WebClientMetricsConfigurationTests.java @@ -31,7 +31,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; @@ -58,7 +59,7 @@ public class WebClientMetricsConfigurationTests { HttpClientMetricsAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void webClientCreatedWithBuilderIsInstrumented() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/reactive/WebFluxMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/reactive/WebFluxMetricsAutoConfigurationTests.java index b603f56c7f6..cb5c87014ed 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/reactive/WebFluxMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/reactive/WebFluxMetricsAutoConfigurationTests.java @@ -29,7 +29,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.reactive.server.WebTestClient; @@ -50,7 +51,7 @@ public class WebFluxMetricsAutoConfigurationTests { AutoConfigurations.of(WebFluxMetricsAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void shouldProvideWebFluxMetricsBeans() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfigurationTests.java index a89008ae147..66728d66814 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfigurationTests.java @@ -42,7 +42,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -69,7 +70,7 @@ public class WebMvcMetricsAutoConfigurationTests { AutoConfigurations.of(WebMvcMetricsAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void backsOffWhenMeterRegistryIsMissing() { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java index 74fee04ed0b..2cec658ad44 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java @@ -27,7 +27,8 @@ import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagem import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @@ -41,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class ManagementContextAutoConfigurationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void childManagementContextShouldStartForEmbeddedServer() { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/EndpointIdTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/EndpointIdTests.java index dca1f4e219b..8f3fddf9808 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/EndpointIdTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/EndpointIdTests.java @@ -19,7 +19,8 @@ package org.springframework.boot.actuate.endpoint; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -32,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException public class EndpointIdTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void ofWhenNullThrowsException() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java index c601738ff21..60b6aa29e75 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/freemarker/FreeMarkerAutoConfigurationTests.java @@ -24,7 +24,8 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.testsupport.BuildOutput; import static org.assertj.core.api.Assertions.assertThat; @@ -38,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class FreeMarkerAutoConfigurationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private final BuildOutput buildOutput = new BuildOutput(getClass()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/influx/InfluxDbAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/influx/InfluxDbAutoConfigurationTests.java index c3da96ac5ba..57c9a60b987 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/influx/InfluxDbAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/influx/InfluxDbAutoConfigurationTests.java @@ -27,7 +27,8 @@ import retrofit2.Retrofit; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.util.ReflectionTestUtils; @@ -44,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class InfluxDbAutoConfigurationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(InfluxDbAutoConfiguration.class)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java index 804dc0a6e61..4b727be724c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jersey/JerseyAutoConfigurationServletContainerTests.java @@ -36,7 +36,8 @@ import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfigurationServ import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,11 +54,11 @@ import static org.assertj.core.api.Assertions.assertThat; */ @SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT) @DirtiesContext -@ExtendWith(OutputCapture.class) +@ExtendWith(OutputExtension.class) public class JerseyAutoConfigurationServletContainerTests { @Test - public void existingJerseyServletIsAmended(OutputCapture output) { + public void existingJerseyServletIsAmended(CapturedOutput output) { assertThat(output) .contains("Configuring existing registration for Jersey servlet"); assertThat(output).contains( diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java index 3619b25c9e3..c84794d4369 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java @@ -43,7 +43,8 @@ import org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationList import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.testsupport.Assume; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -63,7 +64,7 @@ import static org.assertj.core.api.Assertions.contentOf; * @author Stephane Nicoll * @author Dominic Gunn */ -@ExtendWith(OutputCapture.class) +@ExtendWith(OutputExtension.class) public class LiquibaseAutoConfigurationTests { @BeforeEach @@ -254,7 +255,7 @@ public class LiquibaseAutoConfigurationTests { } @Test - public void logging(OutputCapture output) { + public void logging(CapturedOutput output) { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) .run(assertLiquibase((liquibase) -> { Object log = ReflectionTestUtils.getField(liquibase, "log"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java index 4d4476232c5..799b737ed52 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/logging/ConditionEvaluationReportLoggingListenerTests.java @@ -32,7 +32,8 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConf import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.boot.logging.LogLevel; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -55,7 +56,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException public class ConditionEvaluationReportLoggingListenerTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private ConditionEvaluationReportLoggingListener initializer = new ConditionEvaluationReportLoggingListener(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java index d67fc443806..05d5caf6360 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java @@ -45,7 +45,8 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -70,7 +71,7 @@ import static org.mockito.Mockito.verifyZeroInteractions; public class QuartzAutoConfigurationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withPropertyValues("spring.datasource.generate-unique-name=true") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java index 0223e8d4771..20b91ed018c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityAutoConfigurationTests.java @@ -30,7 +30,8 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.test.City; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.boot.web.servlet.filter.OrderedFilter; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -65,7 +66,7 @@ public class SecurityAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void testWebConfiguration() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java index 8e93f40fdf4..ce0eb234084 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/SecurityFilterAutoConfigurationEarlyInitializationTests.java @@ -30,7 +30,8 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConf import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; @@ -53,7 +54,7 @@ import org.springframework.web.bind.annotation.RestController; public class SecurityFilterAutoConfigurationEarlyInitializationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void testSecurityFilterDoesNotCauseEarlyInitialization() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java index 22af3fb6912..2983740076b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/servlet/UserDetailsServiceAutoConfigurationTests.java @@ -25,7 +25,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -58,7 +59,7 @@ public class UserDetailsServiceAutoConfigurationTests { AutoConfigurations.of(UserDetailsServiceAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void testDefaultUsernamePassword() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java index 3e019d04c81..7330fddeb0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java @@ -29,7 +29,8 @@ import org.springframework.boot.task.TaskExecutorCustomizer; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ContextConsumer; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.SyncTaskExecutor; @@ -59,7 +60,7 @@ public class TaskExecutionAutoConfigurationTests { AutoConfigurations.of(TaskExecutionAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void taskExecutorBuilderShouldApplyCustomSettings() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java index 1a67eb50b6c..8421a5162dd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java @@ -37,7 +37,8 @@ import org.thymeleaf.templateresolver.ITemplateResolver; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.testsupport.BuildOutput; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -60,7 +61,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class ThymeleafReactiveAutoConfigurationTests { @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private final BuildOutput buildOutput = new BuildOutput(getClass()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java index 6ebfa800314..8c67f044409 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java @@ -32,7 +32,8 @@ import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFact import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -63,7 +64,7 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests { private final LogIdFilter logIdFilter = new LogIdFilter(); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() .withConfiguration(AutoConfigurations.of( diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java index 2e6694d0e55..6788b7a0dee 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java @@ -22,7 +22,8 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -45,7 +46,7 @@ public class ErrorMvcAutoConfigurationTests { ErrorMvcAutoConfiguration.class)); @RegisterExtension - public OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test public void renderContainsViewWithExceptionDetails() throws Exception { diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/CapturedOutput.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/CapturedOutput.java new file mode 100644 index 00000000000..e7647c4d59d --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/CapturedOutput.java @@ -0,0 +1,314 @@ +/* + * Copyright 2012-2019 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.boot.test.extension; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import org.junit.jupiter.api.extension.Extension; + +import org.springframework.boot.ansi.AnsiOutput; +import org.springframework.boot.ansi.AnsiOutput.Enabled; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * Provides access to {@link System#out System.out} and {@link System#err System.err} + * output that has been capture by the {@link OutputExtension}. Can be used to apply + * assertions either using AssertJ or standard JUnit assertions. For example: + *
+ * assertThat(output).contains("started"); // Checks all output
+ * assertThat(output.getErr()).contains("failed"); // Only checks System.err
+ * assertThat(output.getOut()).contains("ok"); // Only checks System.put
+ * 
+ * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.2.0 + * @see OutputExtension + */ +public class CapturedOutput implements CharSequence, Extension { + + private final Deque systemCaptures = new ArrayDeque<>(); + + private AnsiOutputState ansiOutputState; + + protected CapturedOutput() { + } + + /** + * Push a new system capture session onto the stack. + */ + protected final void push() { + if (this.systemCaptures.isEmpty()) { + this.ansiOutputState = AnsiOutputState.saveAndDisable(); + } + this.systemCaptures.addLast(new SystemCapture()); + } + + /** + * Pop the last system capture session from the stack. + */ + protected final void pop() { + this.systemCaptures.removeLast().release(); + if (this.systemCaptures.isEmpty() && this.ansiOutputState != null) { + this.ansiOutputState.restore(); + this.ansiOutputState = null; + } + } + + @Override + public int length() { + return toString().length(); + } + + @Override + public char charAt(int index) { + return toString().charAt(index); + } + + @Override + public CharSequence subSequence(int start, int end) { + return toString().subSequence(start, end); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof CapturedOutput || obj instanceof CharSequence) { + return getAll().equals(obj.toString()); + } + return false; + } + + @Override + public int hashCode() { + return toString().hashCode(); + } + + @Override + public String toString() { + return getAll(); + } + + /** + * Return all content (both {@link System#out System.out} and {@link System#err + * System.err}) in the order that it was was captured. + * @return all captured output + */ + public String getAll() { + return get((type) -> true); + } + + /** + * Return {@link System#out System.out} content in the order that it was was captured. + * @return {@link System#out System.out} captured output + */ + public String getOut() { + return get(Type.OUT::equals); + } + + /** + * Return {@link System#err System.err} content in the order that it was was captured. + * @return {@link System#err System.err} captured output + */ + public String getErr() { + return get(Type.ERR::equals); + } + + private String get(Predicate filter) { + Assert.state(!this.systemCaptures.isEmpty(), + "No system captures found. Check that you have used @RegisterExtension " + + "or @ExtendWith and the fields are not private"); + StringBuilder builder = new StringBuilder(); + for (SystemCapture systemCapture : this.systemCaptures) { + systemCapture.append(builder, filter); + } + return builder.toString(); + } + + /** + * A capture session that captures {@link System#out System.out} and {@link System#out + * System.err}. + */ + private static class SystemCapture { + + private final PrintStreamCapture out; + + private final PrintStreamCapture err; + + private final List capturedStrings = Collections + .synchronizedList(new ArrayList<>()); + + SystemCapture() { + this.out = new PrintStreamCapture(System.out, this::captureOut); + this.err = new PrintStreamCapture(System.err, this::captureErr); + System.setOut(this.out); + System.setErr(this.err); + } + + public void release() { + System.setOut(this.out.getParent()); + System.setErr(this.err.getParent()); + } + + private void captureOut(String string) { + this.capturedStrings.add(new CapturedString(Type.OUT, string)); + } + + private void captureErr(String string) { + this.capturedStrings.add(new CapturedString(Type.ERR, string)); + } + + public void append(StringBuilder builder, Predicate filter) { + for (CapturedString stringCapture : this.capturedStrings) { + if (filter.test(stringCapture.getType())) { + builder.append(stringCapture); + } + } + } + + } + + /** + * A {@link PrintStream} implementation that captures written strings. + */ + private static class PrintStreamCapture extends PrintStream { + + private final PrintStream parent; + + PrintStreamCapture(PrintStream parent, Consumer copy) { + super(new OutputStreamCapture(getSystemStream(parent), copy)); + this.parent = parent; + } + + public PrintStream getParent() { + return this.parent; + } + + private static PrintStream getSystemStream(PrintStream printStream) { + while (printStream instanceof PrintStreamCapture) { + return ((PrintStreamCapture) printStream).getParent(); + } + return printStream; + } + + } + + /** + * An {@link OutputStream} implementation that captures written strings. + */ + private static class OutputStreamCapture extends OutputStream { + + private final PrintStream systemStream; + + private final Consumer copy; + + OutputStreamCapture(PrintStream systemStream, Consumer copy) { + this.systemStream = systemStream; + this.copy = copy; + } + + @Override + public void write(int b) throws IOException { + write(new byte[] { (byte) (b & 0xFF) }); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.accept(new String(b, off, len)); + this.systemStream.write(b, off, len); + } + + @Override + public void flush() throws IOException { + this.systemStream.flush(); + } + + } + + /** + * A captured string that forms part of the full output. + */ + private static class CapturedString { + + private final Type type; + + private final String string; + + CapturedString(Type type, String string) { + this.type = type; + this.string = string; + } + + public Type getType() { + return this.type; + } + + @Override + public String toString() { + return this.string; + } + + } + + /** + * Types of content that can be captured. + */ + private enum Type { + + OUT, ERR + + } + + /** + * Save disable and restore AnsiOutput without it needing to be on the classpath. + */ + private static class AnsiOutputState { + + private Enabled saved; + + AnsiOutputState() { + this.saved = AnsiOutput.getEnabled(); + AnsiOutput.setEnabled(Enabled.NEVER); + } + + public void restore() { + AnsiOutput.setEnabled(this.saved); + } + + public static AnsiOutputState saveAndDisable() { + if (!ClassUtils.isPresent("org.springframework.boot.ansi.AnsiOutput", + CapturedOutput.class.getClassLoader())) { + return null; + } + return new AnsiOutputState(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputCapture.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputCapture.java deleted file mode 100644 index 8958b7adf98..00000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputCapture.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2012-2019 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.boot.test.extension; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; - -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.ParameterContext; -import org.junit.jupiter.api.extension.ParameterResolutionException; -import org.junit.jupiter.api.extension.ParameterResolver; - -import org.springframework.boot.ansi.AnsiOutput; - -/** - * JUnit5 {@code @Extension} to capture output from System.out and System.err. - * - * @author Madhura Bhave - * @since 2.2.0 - */ -public class OutputCapture implements BeforeEachCallback, AfterEachCallback, - BeforeAllCallback, ParameterResolver, CharSequence { - - private CaptureOutputStream captureOut; - - private CaptureOutputStream captureErr; - - private ByteArrayOutputStream methodLevelCopy; - - private ByteArrayOutputStream classLevelCopy; - - @Override - public void afterEach(ExtensionContext context) { - releaseOutput(); - } - - @Override - public void beforeEach(ExtensionContext context) { - releaseOutput(); - this.methodLevelCopy = new ByteArrayOutputStream(); - captureOutput(this.methodLevelCopy); - } - - private void captureOutput(ByteArrayOutputStream copy) { - AnsiOutputControl.get().disableAnsiOutput(); - this.captureOut = new CaptureOutputStream(System.out, copy); - this.captureErr = new CaptureOutputStream(System.err, copy); - System.setOut(new PrintStream(this.captureOut)); - System.setErr(new PrintStream(this.captureErr)); - } - - private void releaseOutput() { - if (this.captureOut == null) { - return; - } - AnsiOutputControl.get().enabledAnsiOutput(); - System.setOut(this.captureOut.getOriginal()); - System.setErr(this.captureErr.getOriginal()); - this.methodLevelCopy = null; - } - - private void flush() { - try { - this.captureOut.flush(); - this.captureErr.flush(); - } - catch (IOException ex) { - // ignore - } - } - - @Override - public int length() { - return this.toString().length(); - } - - @Override - public char charAt(int index) { - return this.toString().charAt(index); - } - - @Override - public CharSequence subSequence(int start, int end) { - return this.toString().subSequence(start, end); - } - - @Override - public String toString() { - flush(); - if (this.classLevelCopy == null && this.methodLevelCopy == null) { - return ""; - } - StringBuilder builder = new StringBuilder(); - if (this.classLevelCopy != null) { - builder.append(this.classLevelCopy.toString()); - } - builder.append(this.methodLevelCopy.toString()); - return builder.toString(); - } - - @Override - public void beforeAll(ExtensionContext context) { - this.classLevelCopy = new ByteArrayOutputStream(); - captureOutput(this.classLevelCopy); - } - - @Override - public boolean supportsParameter(ParameterContext parameterContext, - ExtensionContext extensionContext) throws ParameterResolutionException { - return OutputCapture.class.equals(parameterContext.getParameter().getType()); - } - - @Override - public Object resolveParameter(ParameterContext parameterContext, - ExtensionContext extensionContext) throws ParameterResolutionException { - return this; - } - - private static class CaptureOutputStream extends OutputStream { - - private final PrintStream original; - - private final OutputStream copy; - - CaptureOutputStream(PrintStream original, OutputStream copy) { - this.original = original; - this.copy = copy; - } - - @Override - public void write(int b) throws IOException { - this.copy.write(b); - this.original.write(b); - this.original.flush(); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - this.copy.write(b, off, len); - this.original.write(b, off, len); - } - - public PrintStream getOriginal() { - return this.original; - } - - @Override - public void flush() throws IOException { - this.copy.flush(); - this.original.flush(); - } - - } - - /** - * Allow AnsiOutput to not be on the test classpath. - */ - private static class AnsiOutputControl { - - public void disableAnsiOutput() { - } - - public void enabledAnsiOutput() { - } - - public static AnsiOutputControl get() { - try { - Class.forName("org.springframework.boot.ansi.AnsiOutput"); - return new AnsiPresentOutputControl(); - } - catch (ClassNotFoundException ex) { - return new AnsiOutputControl(); - } - } - - } - - private static class AnsiPresentOutputControl extends AnsiOutputControl { - - @Override - public void disableAnsiOutput() { - AnsiOutput.setEnabled(AnsiOutput.Enabled.NEVER); - } - - @Override - public void enabledAnsiOutput() { - AnsiOutput.setEnabled(AnsiOutput.Enabled.DETECT); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputExtension.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputExtension.java new file mode 100644 index 00000000000..2fbe8581828 --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/extension/OutputExtension.java @@ -0,0 +1,118 @@ +/* + * Copyright 2012-2019 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.boot.test.extension; + +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** + * JUnit5 {@code @Extension} to capture output {@link System#out System.out} and + * {@link System#err System.err}. Can be used on a test class via + * {@link ExtendWith @ExtendWith}, or on field using + * {@link RegisterExtension @RegisterExtension}. This extension provides access to + * {@link CapturedOutput} instances which can be used to assert that the correct output + * was written. + *

+ * To use with {@link ExtendWith @ExtendWith}, inject the {@link CapturedOutput} as a test + * argument:

+ * @ExtendWith(OutputExtension.class)
+ * class MyTest {
+ *
+ *   @Test
+ *   void test(CapturedOutput output) {
+ *       assertThat(output).contains("ok");
+ *   }
+ *
+ * }
+ * 
+ *

+ * To use with {@link RegisterExtension @RegisterExtension}, use the {@link #capture() + * capture} factory method: argument:

+ * class MyTest {
+ *
+ *   @RegisterExtension
+ *   CapturedOutput output = OutputExtension.capture();
+ *
+ *   @Test
+ *   void test() {
+ *       assertThat(output).contains("ok");
+ *   }
+ *
+ * }
+ * 
+ * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.2.0 + * @see CapturedOutput + */ +public class OutputExtension extends CapturedOutput implements BeforeAllCallback, + AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver { + + OutputExtension() { + // Package private to prevent users from directly creating an instance. + } + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + push(); + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + pop(); + } + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + push(); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + pop(); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, + ExtensionContext extensionContext) throws ParameterResolutionException { + return CapturedOutput.class.equals(parameterContext.getParameter().getType()); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, + ExtensionContext extensionContext) throws ParameterResolutionException { + return this; + } + + /** + * Factory method for use with {@link RegisterExtension @RegisterExtension} fields. + * @return a new {@link CapturedOutput} instance + */ + public static CapturedOutput capture() { + return new OutputExtension(); + } + +} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/CapturedOutputTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/CapturedOutputTests.java new file mode 100644 index 00000000000..489c4e86419 --- /dev/null +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/CapturedOutputTests.java @@ -0,0 +1,180 @@ +/* + * Copyright 2012-2019 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.boot.test.extension; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.NoSuchElementException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Tests for {@link CapturedOutput}. + * + * @author Phillip Webb + */ +class CapturedOutputTests { + + private PrintStream originalOut; + + private PrintStream originalErr; + + private TestPrintStream systemOut; + + private TestPrintStream systemErr; + + private CapturedOutput output = new CapturedOutput(); + + @BeforeEach + void replaceSystemStreams() { + this.originalOut = System.out; + this.originalErr = System.err; + this.systemOut = new TestPrintStream(); + this.systemErr = new TestPrintStream(); + System.setOut(this.systemOut); + System.setErr(this.systemErr); + } + + @AfterEach + void restoreSystemStreams() { + System.setOut(this.originalOut); + System.setErr(this.originalErr); + } + + @Test + void pushWhenEmptyStartsCapture() { + System.out.print("A"); + this.output.push(); + System.out.print("B"); + assertThat(this.output).isEqualTo("B"); + } + + @Test + void pushWhenHasExistingStartesNewCapture() { + System.out.print("A"); + this.output.push(); + System.out.print("B"); + this.output.push(); + System.out.print("C"); + assertThat(this.output).isEqualTo("BC"); + } + + @Test + void popWhenEmptyThrowsException() { + assertThatExceptionOfType(NoSuchElementException.class) + .isThrownBy(this.output::pop); + } + + @Test + void popWhenHasExistingEndsCapture() { + this.output.push(); + System.out.print("A"); + this.output.pop(); + System.out.print("B"); + assertThat(this.systemOut.toString()).isEqualTo("AB"); + } + + @Test + void captureAlsoWritesToSystemOut() { + this.output.push(); + System.out.print("A"); + assertThat(this.systemOut.toString()).isEqualTo("A"); + } + + @Test + void captureAlsoWritesToSystemErr() { + this.output.push(); + System.err.print("A"); + assertThat(this.systemErr.toString()).isEqualTo("A"); + } + + @Test + void lengthReturnsCapturedLength() { + this.output.push(); + System.out.print("ABC"); + assertThat(this.output.length()).isEqualTo(3); + } + + @Test + void charAtReturnsCapturedCharAt() { + this.output.push(); + System.out.print("ABC"); + assertThat(this.output.charAt(1)).isEqualTo('B'); + } + + @Test + void subSequenceReturnsCapturedSubSequence() { + this.output.push(); + System.out.print("ABC"); + assertThat(this.output.subSequence(1, 3)).isEqualTo("BC"); + } + + @Test + void getAllReturnsAllCapturedOutput() { + this.output.push(); + System.out.print("A"); + System.err.print("B"); + System.out.print("C"); + assertThat(this.output.getAll()).isEqualTo("ABC"); + } + + @Test + void toStringReturnsAllCapturedOutput() { + this.output.push(); + System.out.print("A"); + System.err.print("B"); + System.out.print("C"); + assertThat(this.output.toString()).isEqualTo("ABC"); + } + + @Test + void getErrReturnsOnlyCapturedErrOutput() { + this.output.push(); + System.out.print("A"); + System.err.print("B"); + System.out.print("C"); + assertThat(this.output.getErr()).isEqualTo("B"); + } + + @Test + void getOutReturnsOnlyCapturedOutOutput() { + this.output.push(); + System.out.print("A"); + System.err.print("B"); + System.out.print("C"); + assertThat(this.output.getOut()).isEqualTo("AC"); + } + + private static class TestPrintStream extends PrintStream { + + TestPrintStream() { + super(new ByteArrayOutputStream()); + } + + @Override + public String toString() { + return this.out.toString(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputCaptureExtendWithTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputExtensionExtendWithTests.java similarity index 78% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputCaptureExtendWithTests.java rename to spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputExtensionExtendWithTests.java index ab8eac6b2cb..f5f1d616741 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputCaptureExtendWithTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputExtensionExtendWithTests.java @@ -23,21 +23,21 @@ import org.junit.jupiter.api.extension.ExtensionContext; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link OutputCapture} when used via {@link ExtendWith @ExtendWith}. + * Tests for {@link OutputExtension} when used via {@link ExtendWith @ExtendWith}. * * @author Madhura Bhave */ -@ExtendWith(OutputCapture.class) -@ExtendWith(OutputCaptureExtendWithTests.BeforeAllExtension.class) -class OutputCaptureExtendWithTests { +@ExtendWith(OutputExtension.class) +@ExtendWith(OutputExtensionExtendWithTests.BeforeAllExtension.class) +class OutputExtensionExtendWithTests { @Test - void captureShouldReturnOutputCapturedBeforeTestMethod(OutputCapture output) { + void captureShouldReturnOutputCapturedBeforeTestMethod(CapturedOutput output) { assertThat(output).contains("Before all").doesNotContain("Hello"); } @Test - void captureShouldReturnAllCapturedOutput(OutputCapture output) { + void captureShouldReturnAllCapturedOutput(CapturedOutput output) { System.out.println("Hello World"); System.err.println("Error!!!"); assertThat(output).contains("Before all").contains("Hello World") diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputCaptureRegisterExtensionTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputExtensionRegisterExtensionTests.java similarity index 88% rename from spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputCaptureRegisterExtensionTests.java rename to spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputExtensionRegisterExtensionTests.java index c16e761ed67..785eb65fd65 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputCaptureRegisterExtensionTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/extension/OutputExtensionRegisterExtensionTests.java @@ -21,15 +21,15 @@ import org.junit.jupiter.api.extension.RegisterExtension; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link OutputCapture} when used via + * Tests for {@link OutputExtension} when used via * {@link RegisterExtension @RegisterExtension}. * * @author Madhura Bhave */ -class OutputCaptureRegisterExtensionTests { +class OutputExtensionRegisterExtensionTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void captureShouldReturnAllCapturedOutput() { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java index e102a844cc3..ef0882eb3fa 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -54,6 +54,14 @@ public abstract class AnsiOutput { AnsiOutput.enabled = enabled; } + /** + * Returns if ANSI output is enabled + * @return if ANSI enabled, disabled or detected + */ + public static Enabled getEnabled() { + return AnsiOutput.enabled; + } + /** * Sets if the System.console() is known to be available. * @param consoleAvailable if the console is known to be available or {@code null} to @@ -63,10 +71,6 @@ public abstract class AnsiOutput { AnsiOutput.consoleAvailable = consoleAvailable; } - static Enabled getEnabled() { - return AnsiOutput.enabled; - } - /** * Encode a single {@link AnsiElement} if output is enabled. * @param element the element to encode diff --git a/spring-boot-samples/spring-boot-sample-activemq/src/test/java/sample/activemq/SampleActiveMqTests.java b/spring-boot-samples/spring-boot-sample-activemq/src/test/java/sample/activemq/SampleActiveMqTests.java index 27b1173c63d..fa8b60cdff5 100644 --- a/spring-boot-samples/spring-boot-sample-activemq/src/test/java/sample/activemq/SampleActiveMqTests.java +++ b/spring-boot-samples/spring-boot-sample-activemq/src/test/java/sample/activemq/SampleActiveMqTests.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -34,7 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleActiveMqTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Autowired private Producer producer; diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorLog4J2ApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorLog4J2ApplicationTests.java index 28c8425a4f5..f513ae0ad7a 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorLog4J2ApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorLog4J2ApplicationTests.java @@ -26,7 +26,8 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.test.web.servlet.MockMvc; import static org.assertj.core.api.Assertions.assertThat; @@ -49,7 +50,7 @@ class SampleActuatorLog4J2ApplicationTests { .getLogger(SampleActuatorLog4J2ApplicationTests.class); @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Autowired private MockMvc mvc; diff --git a/spring-boot-samples/spring-boot-sample-aop/src/test/java/sample/aop/SampleAopApplicationTests.java b/spring-boot-samples/spring-boot-sample-aop/src/test/java/sample/aop/SampleAopApplicationTests.java index c95ae1ee24d..1f4d54f4a9c 100644 --- a/spring-boot-samples/spring-boot-sample-aop/src/test/java/sample/aop/SampleAopApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-aop/src/test/java/sample/aop/SampleAopApplicationTests.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -34,7 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleAopApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private String profiles; diff --git a/spring-boot-samples/spring-boot-sample-batch/src/test/java/sample/batch/SampleBatchApplicationTests.java b/spring-boot-samples/spring-boot-sample-batch/src/test/java/sample/batch/SampleBatchApplicationTests.java index 770e149344a..7adbbdec0d8 100644 --- a/spring-boot-samples/spring-boot-sample-batch/src/test/java/sample/batch/SampleBatchApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-batch/src/test/java/sample/batch/SampleBatchApplicationTests.java @@ -20,14 +20,15 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.SpringApplication; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; class SampleBatchApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() { diff --git a/spring-boot-samples/spring-boot-sample-data-cassandra/src/test/java/sample/data/cassandra/SampleCassandraApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-cassandra/src/test/java/sample/data/cassandra/SampleCassandraApplicationTests.java index e9eac0401b0..bc19fd14b55 100644 --- a/spring-boot-samples/spring-boot-sample-data-cassandra/src/test/java/sample/data/cassandra/SampleCassandraApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-cassandra/src/test/java/sample/data/cassandra/SampleCassandraApplicationTests.java @@ -25,7 +25,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.TestExecutionListeners.MergeMode; @@ -36,14 +37,14 @@ import static org.assertj.core.api.Assertions.assertThat; */ @TestExecutionListeners(mergeMode = MergeMode.MERGE_WITH_DEFAULTS, listeners = { OrderedCassandraTestExecutionListener.class }) -@ExtendWith(OutputCapture.class) +@ExtendWith(OutputExtension.class) @SpringBootTest @CassandraDataSet(keyspace = "mykeyspace", value = "setup.cql") @EmbeddedCassandra(timeout = 60000) class SampleCassandraApplicationTests { @Test - void testDefaultSettings(OutputCapture output) { + void testDefaultSettings(CapturedOutput output) { Assumptions.assumeFalse(this::runningOnWindows); assertThat(output).contains("firstName='Alice', lastName='Smith'"); } diff --git a/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java index 5bd400c3e00..90380771fb5 100644 --- a/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-couchbase/src/test/java/sample/data/couchbase/SampleCouchbaseApplicationTests.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.core.NestedCheckedException; import static org.assertj.core.api.Assertions.assertThat; @@ -29,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleCouchbaseApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() { diff --git a/spring-boot-samples/spring-boot-sample-data-elasticsearch/src/test/java/sample/data/elasticsearch/SampleElasticsearchApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-elasticsearch/src/test/java/sample/data/elasticsearch/SampleElasticsearchApplicationTests.java index 94ed40f60e2..eba2d225c10 100644 --- a/spring-boot-samples/spring-boot-sample-data-elasticsearch/src/test/java/sample/data/elasticsearch/SampleElasticsearchApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-elasticsearch/src/test/java/sample/data/elasticsearch/SampleElasticsearchApplicationTests.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -33,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleElasticsearchApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() { diff --git a/spring-boot-samples/spring-boot-sample-data-ldap/src/test/java/sample/data/ldap/SampleLdapApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-ldap/src/test/java/sample/data/ldap/SampleLdapApplicationTests.java index ceeb3d19fec..d7a6b090bf7 100644 --- a/spring-boot-samples/spring-boot-sample-data-ldap/src/test/java/sample/data/ldap/SampleLdapApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-ldap/src/test/java/sample/data/ldap/SampleLdapApplicationTests.java @@ -20,7 +20,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -29,12 +30,12 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Phillip Webb */ -@ExtendWith(OutputCapture.class) +@ExtendWith(OutputExtension.class) @SpringBootTest class SampleLdapApplicationTests { @Test - void testDefaultSettings(OutputCapture output) { + void testDefaultSettings(CapturedOutput output) { assertThat(output).contains("cn=Alice Smith"); } diff --git a/spring-boot-samples/spring-boot-sample-data-mongodb/src/test/java/sample/data/mongo/SampleMongoApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-mongodb/src/test/java/sample/data/mongo/SampleMongoApplicationTests.java index ba2702d8107..af1931a6f04 100644 --- a/spring-boot-samples/spring-boot-sample-data-mongodb/src/test/java/sample/data/mongo/SampleMongoApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-mongodb/src/test/java/sample/data/mongo/SampleMongoApplicationTests.java @@ -20,7 +20,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -30,12 +31,12 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Dave Syer * @author Andy Wilkinson */ -@ExtendWith(OutputCapture.class) +@ExtendWith(OutputExtension.class) @SpringBootTest class SampleMongoApplicationTests { @Test - void testDefaultSettings(OutputCapture output) { + void testDefaultSettings(CapturedOutput output) { assertThat(output).contains("firstName='Alice', lastName='Smith'"); } diff --git a/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java index 80e9537bd1d..a84b56936db 100644 --- a/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-neo4j/src/test/java/sample/data/neo4j/SampleNeo4jApplicationTests.java @@ -20,7 +20,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleNeo4jApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() { diff --git a/spring-boot-samples/spring-boot-sample-data-redis/src/test/java/sample/data/redis/SampleRedisApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-redis/src/test/java/sample/data/redis/SampleRedisApplicationTests.java index f76a6c81293..3e9523ca195 100644 --- a/spring-boot-samples/spring-boot-sample-data-redis/src/test/java/sample/data/redis/SampleRedisApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-redis/src/test/java/sample/data/redis/SampleRedisApplicationTests.java @@ -19,7 +19,8 @@ package sample.data.redis; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.data.redis.RedisConnectionFailureException; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleRedisApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() { diff --git a/spring-boot-samples/spring-boot-sample-data-solr/src/test/java/sample/data/solr/SampleSolrApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-solr/src/test/java/sample/data/solr/SampleSolrApplicationTests.java index 866f2ad1c1a..1646d809f7f 100644 --- a/spring-boot-samples/spring-boot-sample-data-solr/src/test/java/sample/data/solr/SampleSolrApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-data-solr/src/test/java/sample/data/solr/SampleSolrApplicationTests.java @@ -19,7 +19,8 @@ package sample.data.solr; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.core.NestedCheckedException; import static org.assertj.core.api.Assertions.assertThat; @@ -27,7 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleSolrApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() throws Exception { diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java b/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java index e93d21fbdd6..db965ca53e1 100644 --- a/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java @@ -19,7 +19,8 @@ package sample.jooq; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -31,7 +32,7 @@ class SampleJooqApplicationTests { private static final String[] NO_ARGS = {}; @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void outputResults() { diff --git a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java index 023941978de..a2e30c82b27 100644 --- a/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-jta-atomikos/src/test/java/sample/atomikos/SampleAtomikosApplicationTests.java @@ -20,7 +20,8 @@ import org.assertj.core.api.Condition; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -32,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleAtomikosApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testTransactionRollback() throws Exception { diff --git a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java index e5b02c03d06..5c2ffc45eec 100644 --- a/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-jta-bitronix/src/test/java/sample/bitronix/SampleBitronixApplicationTests.java @@ -22,7 +22,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.SpringApplication; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.ApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @@ -35,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleBitronixApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testTransactionRollback() throws Exception { diff --git a/spring-boot-samples/spring-boot-sample-liquibase/src/test/java/sample/liquibase/SampleLiquibaseApplicationTests.java b/spring-boot-samples/spring-boot-sample-liquibase/src/test/java/sample/liquibase/SampleLiquibaseApplicationTests.java index 11c254533ac..3ba6699abd5 100644 --- a/spring-boot-samples/spring-boot-sample-liquibase/src/test/java/sample/liquibase/SampleLiquibaseApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-liquibase/src/test/java/sample/liquibase/SampleLiquibaseApplicationTests.java @@ -21,7 +21,8 @@ import java.net.ConnectException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.core.NestedCheckedException; import static org.assertj.core.api.Assertions.assertThat; @@ -29,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleLiquibaseApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() throws Exception { diff --git a/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java b/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java index 07147e93d2d..dc3cd9676f8 100644 --- a/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java @@ -19,14 +19,15 @@ package sample.logback; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; class SampleLogbackApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testLoadedCustomLogbackConfig() throws Exception { diff --git a/spring-boot-samples/spring-boot-sample-profile/src/test/java/sample/profile/SampleProfileApplicationTests.java b/spring-boot-samples/spring-boot-sample-profile/src/test/java/sample/profile/SampleProfileApplicationTests.java index 2ca7bf23272..63665eb7c25 100644 --- a/spring-boot-samples/spring-boot-sample-profile/src/test/java/sample/profile/SampleProfileApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-profile/src/test/java/sample/profile/SampleProfileApplicationTests.java @@ -21,14 +21,15 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; class SampleProfileApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private String profiles; diff --git a/spring-boot-samples/spring-boot-sample-quartz/src/test/java/sample/quartz/SampleQuartzApplicationTests.java b/spring-boot-samples/spring-boot-sample-quartz/src/test/java/sample/quartz/SampleQuartzApplicationTests.java index 9d7a72a25f1..f94a2295688 100644 --- a/spring-boot-samples/spring-boot-sample-quartz/src/test/java/sample/quartz/SampleQuartzApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-quartz/src/test/java/sample/quartz/SampleQuartzApplicationTests.java @@ -20,7 +20,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.SpringApplication; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.context.ConfigurableApplicationContext; import static org.assertj.core.api.Assertions.assertThat; @@ -33,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleQuartzApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void quartzJobIsTriggered() throws InterruptedException { diff --git a/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SampleSimpleApplicationTests.java b/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SampleSimpleApplicationTests.java index f5b1fef4b92..2cca289021d 100644 --- a/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SampleSimpleApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SampleSimpleApplicationTests.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -34,7 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleSimpleApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private String profiles; diff --git a/spring-boot-samples/spring-boot-sample-webservices/src/test/java/sample/webservices/SampleWsApplicationTests.java b/spring-boot-samples/spring-boot-sample-webservices/src/test/java/sample/webservices/SampleWsApplicationTests.java index 09ffb24a977..c6b95084f48 100644 --- a/spring-boot-samples/spring-boot-sample-webservices/src/test/java/sample/webservices/SampleWsApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-webservices/src/test/java/sample/webservices/SampleWsApplicationTests.java @@ -27,7 +27,8 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.ws.client.core.WebServiceTemplate; @@ -37,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; class SampleWsApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); private WebServiceTemplate webServiceTemplate = new WebServiceTemplate(); diff --git a/spring-boot-samples/spring-boot-sample-xml/src/test/java/sample/xml/SampleSpringXmlApplicationTests.java b/spring-boot-samples/spring-boot-sample-xml/src/test/java/sample/xml/SampleSpringXmlApplicationTests.java index 2c584e2b578..cd90885b99c 100644 --- a/spring-boot-samples/spring-boot-sample-xml/src/test/java/sample/xml/SampleSpringXmlApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-xml/src/test/java/sample/xml/SampleSpringXmlApplicationTests.java @@ -19,14 +19,15 @@ package sample.xml; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.boot.test.extension.OutputCapture; +import org.springframework.boot.test.extension.CapturedOutput; +import org.springframework.boot.test.extension.OutputExtension; import static org.assertj.core.api.Assertions.assertThat; class SampleSpringXmlApplicationTests { @RegisterExtension - OutputCapture output = new OutputCapture(); + CapturedOutput output = OutputExtension.capture(); @Test void testDefaultSettings() throws Exception {