Add support for manually managing the RestDocumentationContext
In 1.0, the reliance on JUnit was more widespread than it should have been. It should have been isolated to the JUnit TestRule implementation, RestDocumentation. Unfortunately, RestDocumentation was also an argument to MockMvcRestDocumentation.documentationConfiguration which made it impossible to use Spring REST Docs without having JUnit on the classpath. This commit introduces JUnitRestDocumentation and ManualRestDocumentation. The format is a direct replacement for RestDocumentation which has been reworked to delegate to JUnitRestDocumentation. The latter allows manual management of the RestDocumentationContext, primarily for use with TestNG. A new interface, RestDocumentationContextProvider, has been introduced. It is implemented by RestDocumentation, JUnitRestDocumentation and ManualRestDocumentation. MockMvcRestDocumentation.documentationConfiguration has been overridden to also accept a RestDocumentationContextProvider. The method that accepts a RestDocumentation has been deprecated, as has RestDocumentation itself. The documentation has been updated to encourage the use of JUnitRestDocumentation and a sample illustrating the use of Spring REST Docs with TestNG has been added. Closes gh-171
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2014-2016 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
|
||||
*
|
||||
* http://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.restdocs;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
/**
|
||||
* A JUnit {@link TestRule} used to automatically manage the
|
||||
* {@link RestDocumentationContext}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class JUnitRestDocumentation implements RestDocumentationContextProvider, TestRule {
|
||||
|
||||
private final ManualRestDocumentation delegate;
|
||||
|
||||
/**
|
||||
* Creates a new {@code JUnitRestDocumentation} instance that will generate snippets
|
||||
* to the given {@code outputDirectory}.
|
||||
*
|
||||
* @param outputDirectory the output directory
|
||||
*/
|
||||
public JUnitRestDocumentation(String outputDirectory) {
|
||||
this.delegate = new ManualRestDocumentation(outputDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, final Description description) {
|
||||
return new Statement() {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
Class<?> testClass = description.getTestClass();
|
||||
String methodName = description.getMethodName();
|
||||
JUnitRestDocumentation.this.delegate.beforeTest(testClass, methodName);
|
||||
try {
|
||||
base.evaluate();
|
||||
}
|
||||
finally {
|
||||
JUnitRestDocumentation.this.delegate.afterTest();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestDocumentationContext beforeOperation() {
|
||||
return this.delegate.beforeOperation();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.restdocs;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* {@code ManualRestDocumentation} is used to manually manage the
|
||||
* {@link RestDocumentationContext}. Primarly intended for use with TestNG, but suitable
|
||||
* for use in any environment where manual management of the context is required.
|
||||
* <p>
|
||||
* Users of JUnit should use {@link JUnitRestDocumentation} and take advantage of its
|
||||
* Rule-based support for automatic management of the context.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final class ManualRestDocumentation implements RestDocumentationContextProvider {
|
||||
|
||||
private final File outputDirectory;
|
||||
|
||||
private RestDocumentationContext context;
|
||||
|
||||
/**
|
||||
* Creates a new {@code ManualRestDocumentation} instance that will generate snippets
|
||||
* to the given {@code outputDirectory}.
|
||||
*
|
||||
* @param outputDirectory the output directory
|
||||
*/
|
||||
public ManualRestDocumentation(String outputDirectory) {
|
||||
this.outputDirectory = new File(outputDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that a test is about to begin. Creates a
|
||||
* {@link RestDocumentationContext} for the test on the given {@code testClass} with
|
||||
* the given {@code testMethodName}. Must be followed by a call to
|
||||
* {@link #afterTest()} once the test has completed.
|
||||
*
|
||||
* @param testClass the test class
|
||||
* @param testMethodName the name of the test method
|
||||
* @throws IllegalStateException if a context has already be created
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void beforeTest(Class<?> testClass, String testMethodName) {
|
||||
if (this.context != null) {
|
||||
throw new IllegalStateException(
|
||||
"Context already exists. Did you forget to call afterTest()?");
|
||||
}
|
||||
this.context = new RestDocumentationContext(testClass, testMethodName,
|
||||
this.outputDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that a test has completed. Clears the {@link RestDocumentationContext}
|
||||
* that was previously established by a call to {@link #beforeTest(Class, String)}.
|
||||
*/
|
||||
public void afterTest() {
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestDocumentationContext beforeOperation() {
|
||||
this.context.getAndIncrementStepCount();
|
||||
return this.context;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.restdocs;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
@@ -27,13 +25,12 @@ import org.junit.runners.model.Statement;
|
||||
* JUnit tests.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
* @deprecated Since 1.1 in favor of {@link JUnitRestDocumentation}
|
||||
*/
|
||||
public class RestDocumentation implements TestRule {
|
||||
@Deprecated
|
||||
public class RestDocumentation implements TestRule, RestDocumentationContextProvider {
|
||||
|
||||
private final String outputDirectory;
|
||||
|
||||
private RestDocumentationContext context;
|
||||
private final JUnitRestDocumentation delegate;
|
||||
|
||||
/**
|
||||
* Creates a new {@code RestDocumentation} instance that will generate snippets to the
|
||||
@@ -42,40 +39,17 @@ public class RestDocumentation implements TestRule {
|
||||
* @param outputDirectory the output directory
|
||||
*/
|
||||
public RestDocumentation(String outputDirectory) {
|
||||
this.outputDirectory = outputDirectory;
|
||||
this.delegate = new JUnitRestDocumentation(outputDirectory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, final Description description) {
|
||||
return new Statement() {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
Class<?> testClass = description.getTestClass();
|
||||
String methodName = description.getMethodName();
|
||||
RestDocumentation.this.context = new RestDocumentationContext(testClass,
|
||||
methodName, new File(RestDocumentation.this.outputDirectory));
|
||||
try {
|
||||
base.evaluate();
|
||||
}
|
||||
finally {
|
||||
RestDocumentation.this.context = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return this.delegate.apply(base, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that a RESTful operation that should be documented is about to be
|
||||
* performed. Returns a {@link RestDocumentationContext} for the operation.
|
||||
*
|
||||
* @return the context for the operation
|
||||
*/
|
||||
@Override
|
||||
public RestDocumentationContext beforeOperation() {
|
||||
this.context.getAndIncrementStepCount();
|
||||
return this.context;
|
||||
return this.delegate.beforeOperation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,9 @@ public final class RestDocumentationContext {
|
||||
* @param testClass the class whose test is being executed
|
||||
* @param testMethodName the name of the test method that is being executed
|
||||
* @param outputDirectory the directory to which documentation should be written.
|
||||
* @deprecated Since 1.1 in favor of {@link ManualRestDocumentation}.
|
||||
*/
|
||||
@Deprecated
|
||||
public RestDocumentationContext(Class<?> testClass, String testMethodName,
|
||||
File outputDirectory) {
|
||||
this.testClass = testClass;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.restdocs;
|
||||
|
||||
/**
|
||||
* A {@code RestDocumentationContextProvider} is used to provide access to the
|
||||
* {@link RestDocumentationContext}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface RestDocumentationContextProvider {
|
||||
|
||||
/**
|
||||
* Returns a {@link RestDocumentationContext} for the operation that is about to be
|
||||
* performed.
|
||||
*
|
||||
* @return the context for the operation
|
||||
*/
|
||||
RestDocumentationContext beforeOperation();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user