Polish OutputCapture and its JUnit Jupiter extension

- Polish Javadoc
- Improve error message in OutputCapture
- Use ExtensionContext.Store in OutputCaptureExtension

See gh-17049
pull/17587/head
Sam Brannen 6 years ago committed by Andy Wilkinson
parent b092cb7b7f
commit e1c595a67f

@ -23,7 +23,7 @@ package org.springframework.boot.test.system;
* standard JUnit assertions. For example: <pre class="code">
* 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
* assertThat(output.getOut()).contains("ok"); // Only checks System.out
* </pre>
*
* @author Madhura Bhave

@ -38,6 +38,8 @@ import org.springframework.util.ClassUtils;
* @author Madhura Bhave
* @author Phillip Webb
* @author Andy Wilkinson
* @author Sam Brannen
* @since 2.2.0
* @see OutputCaptureExtension
* @see OutputCaptureRule
*/
@ -125,7 +127,12 @@ class OutputCapture implements CapturedOutput {
}
private String get(Predicate<Type> filter) {
Assert.state(!this.systemCaptures.isEmpty(), "No system captures found. Check that you have used @ExtendWith.");
Assert.state(!this.systemCaptures.isEmpty(),
"No system captures found. When using JUnit 4, ensure that you have "
+ "registered the OutputCaptureRule via @ClassRule or @Rule "
+ "and that the field is public. "
+ "When using JUnit Jupiter, ensure that you have registered "
+ "the OutputCaptureExtension via @ExtendWith.");
StringBuilder builder = new StringBuilder();
for (SystemCapture systemCapture : this.systemCaptures) {
systemCapture.append(builder, filter);

@ -22,19 +22,21 @@ 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.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
/**
* JUnit 5 {@code @Extension} to capture {@link System#out System.out} and
* {@link System#err System.err}. Can be used on a test class via
* {@link ExtendWith @ExtendWith}. This extension provides {@link ParameterResolver
* parameter resolution} for a {@link CapturedOutput} instance which can be used to assert
* that the correct output was written.
* JUnit Jupiter {@code @Extension} to capture {@link System#out System.out} and
* {@link System#err System.err}. Can be registered for an entire test class or for an
* individual test method via {@link ExtendWith @ExtendWith}. This extension provides
* {@linkplain ParameterResolver parameter resolution} for a {@link CapturedOutput}
* instance which can be used to assert that the correct output was written.
* <p>
* To use, add {@link ExtendWith @ExtendWith} and inject the {@link CapturedOutput} as an
* argument to your test class constructor or test method:
* To use with {@link ExtendWith @ExtendWith}, inject the {@link CapturedOutput} as an
* argument to your test class constructor, test method, or lifecycle methods:
*
* <pre class="code">
* &#064;ExtendWith(OutputCaptureExtension.class)
@ -42,7 +44,15 @@ import org.junit.jupiter.api.extension.ParameterResolver;
*
* &#064;Test
* void test(CapturedOutput output) {
* System.out.println("ok");
* assertThat(output).contains("ok");
* System.err.println("error");
* }
*
* &#064;AfterEach
* void after(CapturedOutput output) {
* assertThat(output.getOut()).contains("ok");
* assertThat(output.getErr()).contains("error");
* }
*
* }
@ -51,36 +61,35 @@ import org.junit.jupiter.api.extension.ParameterResolver;
* @author Madhura Bhave
* @author Phillip Webb
* @author Andy Wilkinson
* @author Sam Brannen
* @since 2.2.0
* @see CapturedOutput
*/
public class OutputCaptureExtension
implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {
private final OutputCapture outputCapture = new OutputCapture();
OutputCaptureExtension() {
// Package private to prevent users from directly creating an instance.
}
@Override
public void beforeAll(ExtensionContext context) throws Exception {
this.outputCapture.push();
getOutputCapture(context).push();
}
@Override
public void afterAll(ExtensionContext context) throws Exception {
this.outputCapture.pop();
getOutputCapture(context).pop();
}
@Override
public void beforeEach(ExtensionContext context) throws Exception {
this.outputCapture.push();
getOutputCapture(context).push();
}
@Override
public void afterEach(ExtensionContext context) throws Exception {
this.outputCapture.pop();
getOutputCapture(context).pop();
}
@Override
@ -90,9 +99,16 @@ public class OutputCaptureExtension
}
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
return this.outputCapture;
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
return getOutputCapture(extensionContext);
}
private OutputCapture getOutputCapture(ExtensionContext context) {
return getStore(context).getOrComputeIfAbsent(OutputCapture.class);
}
private Store getStore(ExtensionContext context) {
return context.getStore(Namespace.create(getClass()));
}
}

Loading…
Cancel
Save