+ * assertThat(output).contains("started"); // Checks all output
+ * assertThat(output.getErr()).contains("failed"); // Only checks System.err
+ * assertThat(output.getOut()).contains("ok"); // Only checks System.out
+ *
+ *
+ * @author Madhura Bhave
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ */
+public interface CapturedOutput extends CharSequence {
+
+ @Override
+ default int length() {
+ return toString().length();
+ }
+
+ @Override
+ default char charAt(int index) {
+ return toString().charAt(index);
+ }
+
+ @Override
+ default CharSequence subSequence(int start, int end) {
+ return toString().subSequence(start, end);
+ }
+
+ /**
+ * Return all content (both {@link System#out System.out} and {@link System#err
+ * System.err}) in the order that it was captured.
+ * @return all captured output
+ */
+ String getAll();
+
+ /**
+ * Return {@link System#out System.out} content in the order that it was captured.
+ * @return {@link System#out System.out} captured output
+ */
+ String getOut();
+
+ /**
+ * Return {@link System#err System.err} content in the order that it was captured.
+ * @return {@link System#err System.err} captured output
+ */
+ String getErr();
+
+}
diff --git a/spring-restdocs-core/src/testFixtures/java/org/springframework/restdocs/testfixtures/OutputCapture.java b/spring-restdocs-core/src/testFixtures/java/org/springframework/restdocs/testfixtures/OutputCapture.java
index d8c86ed6..eef8d6a3 100644
--- a/spring-restdocs-core/src/testFixtures/java/org/springframework/restdocs/testfixtures/OutputCapture.java
+++ b/spring-restdocs-core/src/testFixtures/java/org/springframework/restdocs/testfixtures/OutputCapture.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 the original author or authors.
+ * Copyright 2014-2022 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.
@@ -16,139 +16,257 @@
package org.springframework.restdocs.testfixtures;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Deque;
import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
-import org.assertj.core.api.HamcrestCondition;
-import org.hamcrest.Matcher;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hamcrest.Matchers.allOf;
+import org.springframework.util.Assert;
/**
- * JUnit {@code @Rule} to capture output from System.out and System.err.
+ * Provides support for capturing {@link System#out System.out} and {@link System#err
+ * System.err}.
*
+ * @author Madhura Bhave
* @author Phillip Webb
* @author Andy Wilkinson
+ * @author Sam Brannen
+ * @see OutputCaptureRule
*/
-public class OutputCapture implements TestRule {
+class OutputCapture implements CapturedOutput {
- private CaptureOutputStream captureOut;
+ private final Deque+ * To use add as a {@link Rule @Rule}: + * + *
+ * public class MyTest {
+ *
+ * @Rule
+ * public OutputCaptureRule output = new OutputCaptureRule();
+ *
+ * @Test
+ * public void test() {
+ * assertThat(output).contains("ok");
+ * }
+ *
+ * }
+ *
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ */
+public class OutputCaptureRule implements TestRule, CapturedOutput {
+
+ private final OutputCapture delegate = new OutputCapture();
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ OutputCaptureRule.this.delegate.push();
+ try {
+ base.evaluate();
+ }
+ finally {
+ OutputCaptureRule.this.delegate.pop();
+ }
+ }
+ };
+ }
+
+ @Override
+ public String getAll() {
+ return this.delegate.getAll();
+ }
+
+ @Override
+ public String getOut() {
+ return this.delegate.getOut();
+ }
+
+ @Override
+ public String getErr() {
+ return this.delegate.getErr();
+ }
+
+ @Override
+ public String toString() {
+ return this.delegate.toString();
+ }
+
+}