hasNotFailed() {
+ if (this.startupFailure != null) {
+ throwAssertionError(new BasicErrorMessageFactory(
+ "%nExpecting:%n <%s>%nto have not failed:%nbut context failed to start",
+ getApplicationContext()));
+ }
+ return this;
+ }
+
+ protected final C getApplicationContext() {
+ return this.actual;
+ }
+
+ protected final Throwable getStartupFailure() {
+ return this.startupFailure;
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ApplicationContextTester.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ApplicationContextTester.java
new file mode 100644
index 0000000000..f133c27d84
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ApplicationContextTester.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+/**
+ * A {@link AbstractApplicationContextTester ApplicationContext tester} for a standard,
+ * non-web environment {@link ConfigurableApplicationContext}.
+ *
+ * See {@link AbstractApplicationContextTester} for details.
+ *
+ * @author Stephane Nicoll
+ * @author Andy Wilkinson
+ * @author Phillip Webb
+ * @since 2.0.0
+ */
+public class ApplicationContextTester extends
+ AbstractApplicationContextTester {
+
+ /**
+ * Create a new {@link ApplicationContextTester} instance using an
+ * {@link AnnotationConfigApplicationContext} as the underlying source.
+ */
+ public ApplicationContextTester() {
+ this(AnnotationConfigApplicationContext::new);
+ }
+
+ /**
+ * Create a new {@link ApplicationContextTester} instance using the specified
+ * {@code contextFactory} as the underlying source.
+ * @param contextFactory a supplier that returns a new instance on each call
+ */
+ public ApplicationContextTester(
+ Supplier contextFactory) {
+ super(contextFactory);
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertProviderApplicationContext.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertProviderApplicationContext.java
new file mode 100644
index 0000000000..7ea2860d7b
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertProviderApplicationContext.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.io.Closeable;
+import java.lang.reflect.Proxy;
+import java.util.function.Supplier;
+
+import org.assertj.core.api.AssertProvider;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.Assert;
+
+/**
+ * An {@link ApplicationContext} that additionally supports AssertJ style assertions. Can
+ * be used to decorate and existing application context or an application context that
+ * failed to start.
+ *
+ * Assertions can be applied using the standard AssertJ {@code assertThat(...)} style (see
+ * {@link ApplicationContextAssert} for a complete list). For example:
+ * assertThat(applicationContext).hasSingleBean(MyBean.class);
+ *
+ *
+ * If the original {@link ApplicationContext} is needed for any reason the
+ * {@link #getSourceApplicationContext()} method can be used.
+ *
+ * Any {@link ApplicationContext} method called on a context that has failed to start will
+ * throw an {@link IllegalStateException}.
+ *
+ * @param The application context type
+ * @author Phillip Webb
+ * @see AssertableApplicationContext
+ * @see AssertableWebApplicationContext
+ * @see AssertableReactiveWebApplicationContext
+ * @see ApplicationContextAssert
+ */
+interface AssertProviderApplicationContext extends
+ ApplicationContext, AssertProvider>, Closeable {
+
+ /**
+ * Return an assert for AspectJ.
+ * @return an AspectJ assert
+ * @deprecated use standard AssertJ {@code assertThat(context)...} calls instead.
+ */
+ @Deprecated
+ @Override
+ ApplicationContextAssert assertThat();
+
+ /**
+ * Return the original source {@link ApplicationContext}.
+ * @return the source application context
+ * @throws IllegalStateException if the source context failed to start
+ */
+ C getSourceApplicationContext();
+
+ /**
+ * Return the original source {@link ApplicationContext}, casting it to the requested
+ * type.
+ * @param the context type
+ * @param requiredType the required context type
+ * @return the source application context
+ * @throws IllegalStateException if the source context failed to start
+ */
+ T getSourceApplicationContext(Class requiredType);
+
+ /**
+ * Return the failure that caused application context to fail or {@code null} if the
+ * context started without issue.
+ * @return the startup failure or {@code null}
+ */
+ Throwable getStartupFailure();
+
+ @Override
+ void close();
+
+ /**
+ * Factory method to create a new {@link AssertProviderApplicationContext} instance.
+ * @param the assert provider type
+ * @param the context type
+ * @param type the type of {@link AssertProviderApplicationContext} required (must be
+ * an interface)
+ * @param contextType the type of {@link ApplicationContext} being managed (must be an
+ * interface)
+ * @param contextSupplier a supplier that will either return a fully configured
+ * {@link ApplicationContext} or throw an exception if the context fails to start.
+ * @return a {@link AssertProviderApplicationContext} instance
+ */
+ @SuppressWarnings("unchecked")
+ static , C extends ApplicationContext> T get(
+ Class type, Class extends C> contextType,
+ Supplier extends C> contextSupplier) {
+ Assert.notNull(type, "Type must not be null");
+ Assert.isTrue(type.isInterface(), "Type must be an interface");
+ Assert.notNull(contextType, "ContextType must not be null");
+ Assert.isTrue(contextType.isInterface(), "ContextType must be an interface");
+ Class>[] interfaces = { type, contextType };
+ return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
+ interfaces, new AssertProviderApplicationContextInvocationHandler(
+ contextType, contextSupplier));
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertProviderApplicationContextInvocationHandler.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertProviderApplicationContextInvocationHandler.java
new file mode 100644
index 0000000000..64feba0fc2
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertProviderApplicationContextInvocationHandler.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.function.Supplier;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.Assert;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * {@link InvocationHandler} used by {@link AssertProviderApplicationContext} generated
+ * proxies.
+ *
+ * @author Phillip Webb
+ */
+class AssertProviderApplicationContextInvocationHandler implements InvocationHandler {
+
+ private final Class> applicationContextType;
+
+ private final ApplicationContext applicationContext;
+
+ private final RuntimeException startupFailure;
+
+ AssertProviderApplicationContextInvocationHandler(Class> applicationContextType,
+ Supplier> contextSupplier) {
+ this.applicationContextType = applicationContextType;
+ Object contextOrStartupFailure = getContextOrStartupFailure(contextSupplier);
+ if (contextOrStartupFailure instanceof RuntimeException) {
+ this.applicationContext = null;
+ this.startupFailure = (RuntimeException) contextOrStartupFailure;
+ }
+ else {
+ this.applicationContext = (ApplicationContext) contextOrStartupFailure;
+ this.startupFailure = null;
+ }
+ }
+
+ private Object getContextOrStartupFailure(Supplier> contextSupplier) {
+ try {
+ return contextSupplier.get();
+ }
+ catch (RuntimeException ex) {
+ return ex;
+ }
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (isToString(method)) {
+ return toString();
+ }
+ if (isGetSourceContext(method)) {
+ return getSourceContext(args);
+ }
+ if (isGetStartupFailure(method)) {
+ return getStartupFailure();
+ }
+ if (isAssertThat(method)) {
+ return getAssertThat(proxy);
+ }
+ if (isCloseMethod(method)) {
+ return invokeClose();
+ }
+ return invokeApplicationContextMethod(method, args);
+ }
+
+ private boolean isToString(Method method) {
+ return ("toString".equals(method.getName()) && method.getParameterCount() == 0);
+ }
+
+ @Override
+ public String toString() {
+ if (this.startupFailure != null) {
+ return "Unstarted application context "
+ + this.applicationContextType.getName() + "[startupFailure="
+ + this.startupFailure.getClass().getName() + "]";
+ }
+ ToStringBuilder builder = new ToStringBuilder(this.applicationContext)
+ .append("id", this.applicationContext.getId())
+ .append("applicationName", this.applicationContext.getApplicationName())
+ .append("beanDefinitionCount",
+ this.applicationContext.getBeanDefinitionCount());
+ return "Started application " + builder;
+ }
+
+ private boolean isGetSourceContext(Method method) {
+ return "getSourceApplicationContext".equals(method.getName())
+ && ((method.getParameterCount() == 0) || Arrays.equals(
+ new Class>[] { Class.class }, method.getParameterTypes()));
+ }
+
+ private Object getSourceContext(Object[] args) {
+ ApplicationContext context = getStartedApplicationContext();
+ if (!ObjectUtils.isEmpty(args)) {
+ Assert.isInstanceOf((Class>) args[0], context);
+ }
+ return context;
+ }
+
+ private boolean isGetStartupFailure(Method method) {
+ return ("getStartupFailure".equals(method.getName())
+ && method.getParameterCount() == 0);
+ }
+
+ private Object getStartupFailure() {
+ return this.startupFailure;
+ }
+
+ private boolean isAssertThat(Method method) {
+ return ("assertThat".equals(method.getName()) && method.getParameterCount() == 0);
+ }
+
+ private Object getAssertThat(Object proxy) {
+ return new ApplicationContextAssert(
+ (ApplicationContext) proxy, this.startupFailure);
+ }
+
+ private boolean isCloseMethod(Method method) {
+ return ("close".equals(method.getName()) && method.getParameterCount() == 0);
+ }
+
+ private Object invokeClose() throws IOException {
+ if (this.applicationContext instanceof Closeable) {
+ ((Closeable) this.applicationContext).close();
+ }
+ return null;
+ }
+
+ private Object invokeApplicationContextMethod(Method method, Object[] args)
+ throws Throwable {
+ try {
+ return method.invoke(getStartedApplicationContext(), args);
+ }
+ catch (InvocationTargetException ex) {
+ throw ex.getTargetException();
+ }
+ }
+
+ private ApplicationContext getStartedApplicationContext() {
+ if (this.startupFailure != null) {
+ throw new IllegalStateException(toString() + " failed to start",
+ this.startupFailure);
+ }
+ return this.applicationContext;
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableApplicationContext.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableApplicationContext.java
new file mode 100644
index 0000000000..8ac8fe82cc
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableApplicationContext.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * An {@link ApplicationContext} that additionally supports AssertJ style assertions. Can
+ * be used to decorate and existing application context or an application context that
+ * failed to start.
+ *
+ * See {@link AssertProviderApplicationContext} for more details.
+ *
+ * @author Phillip Webb
+ * @since 2.0.0
+ * @see ApplicationContextTester
+ * @see ApplicationContext
+ */
+public interface AssertableApplicationContext
+ extends AssertProviderApplicationContext {
+
+ /**
+ * Factory method to create a new {@link AssertableApplicationContext} instance.
+ * @param contextSupplier a supplier that will either return a fully configured
+ * {@link ConfigurableApplicationContext} or throw an exception if the context fails
+ * to start.
+ * @return an {@link AssertableApplicationContext} instance
+ */
+ static AssertableApplicationContext get(
+ Supplier extends ConfigurableApplicationContext> contextSupplier) {
+ return AssertProviderApplicationContext.get(AssertableApplicationContext.class,
+ ConfigurableApplicationContext.class, contextSupplier);
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableReactiveWebApplicationContext.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableReactiveWebApplicationContext.java
new file mode 100644
index 0000000000..86e5703d4f
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableReactiveWebApplicationContext.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext;
+import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
+
+/**
+ * A {@link ReactiveWebApplicationContext} that additionally supports AssertJ style
+ * assertions. Can be used to decorate and existing reactive web application context or an
+ * application context that failed to start.
+ *
+ * See {@link AssertProviderApplicationContext} for more details.
+ *
+ * @author Phillip Webb
+ * @since 2.0.0
+ * @see ReactiveWebApplicationContext
+ * @see ReactiveWebApplicationContext
+ */
+public interface AssertableReactiveWebApplicationContext extends
+ AssertProviderApplicationContext,
+ ReactiveWebApplicationContext {
+
+ /**
+ * Factory method to create a new {@link AssertableReactiveWebApplicationContext}
+ * instance.
+ * @param contextSupplier a supplier that will either return a fully configured
+ * {@link ConfigurableReactiveWebApplicationContext} or throw an exception if the
+ * context fails to start.
+ * @return a {@link AssertableReactiveWebApplicationContext} instance
+ */
+ static AssertableReactiveWebApplicationContext get(
+ Supplier extends ConfigurableReactiveWebApplicationContext> contextSupplier) {
+ return AssertProviderApplicationContext.get(
+ AssertableReactiveWebApplicationContext.class,
+ ConfigurableReactiveWebApplicationContext.class, contextSupplier);
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableWebApplicationContext.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableWebApplicationContext.java
new file mode 100644
index 0000000000..a5815c332c
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/AssertableWebApplicationContext.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.springframework.web.context.ConfigurableWebApplicationContext;
+import org.springframework.web.context.WebApplicationContext;
+
+/**
+ * A {@link WebApplicationContext} that additionally supports AssertJ style assertions.
+ * Can be used to decorate and existing servlet web application context or an application
+ * context that failed to start.
+ *
+ * See {@link AssertProviderApplicationContext} for more details.
+ *
+ * @author Phillip Webb
+ * @since 2.0.0
+ * @see WebApplicationContextTester
+ * @see WebApplicationContext
+ */
+public interface AssertableWebApplicationContext
+ extends AssertProviderApplicationContext,
+ WebApplicationContext {
+
+ /**
+ * Factory method to create a new {@link AssertableWebApplicationContext} instance.
+ * @param contextSupplier a supplier that will either return a fully configured
+ * {@link ConfigurableWebApplicationContext} or throw an exception if the context
+ * fails to start.
+ * @return a {@link AssertableWebApplicationContext} instance
+ */
+ static AssertableWebApplicationContext get(
+ Supplier extends ConfigurableWebApplicationContext> contextSupplier) {
+ return AssertProviderApplicationContext.get(AssertableWebApplicationContext.class,
+ ConfigurableWebApplicationContext.class, contextSupplier);
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextConsumer.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextConsumer.java
index aa6fb8fb77..f4523d9748 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextConsumer.java
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextConsumer.java
@@ -16,24 +16,26 @@
package org.springframework.boot.test.context;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.ApplicationContext;
/**
- * Callback interface used in tests to process a running
- * {@link ConfigurableApplicationContext} with the ability to throw a (checked) exception.
+ * Callback interface used to process an {@link ApplicationContext} with the ability to
+ * throw a (checked) exception.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
+ * @param The application context type
* @since 2.0.0
+ * @see AbstractApplicationContextTester
*/
@FunctionalInterface
-public interface ContextConsumer {
+public interface ContextConsumer {
/**
* Performs this operation on the supplied {@code context}.
* @param context the application context to consume
* @throws Throwable any exception that might occur in assertions
*/
- void accept(ConfigurableApplicationContext context) throws Throwable;
+ void accept(C context) throws Throwable;
}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextLoader.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextLoader.java
deleted file mode 100644
index 421ba80814..0000000000
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ContextLoader.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2012-2017 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.boot.test.context;
-
-import java.util.function.Consumer;
-
-import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.mock.web.MockServletContext;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-
-/**
- * Manage the lifecycle of an {@link ApplicationContext}. Such helper is best used as a
- * field of a test class, describing the shared configuration required for the test:
- *
- *
- * public class FooAutoConfigurationTests {
- *
- * private final ContextLoader contextLoader = ContextLoader.standard()
- * .autoConfig(FooAutoConfiguration.class).env("spring.foo=bar");
- *
- * }
- *
- *
- * The initialization above makes sure to register {@code FooAutoConfiguration} for all
- * tests and set the {@code spring.foo} property to {@code bar} unless specified
- * otherwise.
- *
- *
- * Based on the configuration above, a specific test can simulate what would happen if the
- * user customizes a property and/or provides its own configuration:
- *
- *
- * public class FooAutoConfigurationTests {
- *
- * @Test
- * public someTest() {
- * this.contextLoader.config(UserConfig.class).env("spring.foo=biz")
- * .load(context -> {
- * // assertions using the context
- * });
- * }
- *
- * }
- *
- *
- * The test above includes an extra {@code UserConfig} class that is guaranteed to be
- * processed before any auto-configuration. Also, {@code spring.foo} has
- * been overwritten to {@code biz}. The {@link #load(ContextConsumer) load} method takes a
- * consumer that can use the context to assert its state. Upon completion, the context is
- * automatically closed.
- *
- *
- * Web environment can easily be simulated using the {@link #servletWeb()} and
- * {@link #reactiveWeb()} factory methods.
- *
- *
- * If a failure scenario has to be tested, {@link #loadAndFail(Consumer)} can be used
- * instead: it expects the startup of the context to fail and call the {@link Consumer}
- * with the exception for further assertions.
- *
- * @author Stephane Nicoll
- * @author Andy Wilkinson
- * @since 2.0.0
- */
-public interface ContextLoader {
-
- /**
- * Set the specified system property prior to loading the context and restore its
- * previous value once the consumer has been invoked and the context closed. If the
- * {@code value} is {@code null} this removes any prior customization for that key.
- * @param key the system property
- * @param value the value (can be null to remove any existing customization)
- * @return this instance
- */
- ContextLoader systemProperty(String key, String value);
-
- /**
- * Add the specified property pairs. Key-value pairs can be specified with colon (":")
- * or equals ("=") separators. Override matching keys that might have been specified
- * previously.
- * @param pairs the key-value pairs for properties that need to be added to the
- * environment
- * @return this instance
- */
- ContextLoader env(String... pairs);
-
- /**
- * Add the specified user configuration classes.
- * @param configs the user configuration classes to add
- * @return this instance
- */
- ContextLoader config(Class>... configs);
-
- /**
- * Add the specified auto-configuration classes.
- * @param autoConfigurations the auto-configuration classes to add
- * @return this instance
- */
- ContextLoader autoConfig(Class>... autoConfigurations);
-
- /**
- * Add the specified auto-configurations at the beginning (in that order) so that it
- * is applied before any other existing auto-configurations, but after any user
- * configuration. If {@code A} and {@code B} are specified, {@code A} will be
- * processed, then {@code B} and finally the rest of the existing auto-configuration.
- * @param autoConfigurations the auto-configuration to add
- * @return this instance
- */
- ContextLoader autoConfigFirst(Class>... autoConfigurations);
-
- /**
- * Customize the {@link ClassLoader} that the {@link ApplicationContext} should use.
- * Customizing the {@link ClassLoader} is an effective manner to hide resources from
- * the classpath.
- * @param classLoader the classloader to use (can be null to use the default)
- * @return this instance
- * @see HidePackagesClassLoader
- */
- ContextLoader classLoader(ClassLoader classLoader);
-
- /**
- * Configure the
- * {@link org.springframework.context.ConfigurableApplicationContext#setParent(ApplicationContext)
- * parent} of the {@link ApplicationContext}.
- *
- * @param parent the parent
- * @return this instance
- */
- ContextLoader parent(ApplicationContext parent);
-
- /**
- * Create and refresh a new {@link ApplicationContext} based on the current state of
- * this loader. The context is consumed by the specified {@code consumer} and closed
- * upon completion.
- * @param consumer the consumer of the created {@link ApplicationContext}
- */
- void load(ContextConsumer consumer);
-
- /**
- * Create and refresh a new {@link ApplicationContext} based on the current state of
- * this loader that this expected to fail. If the context does not fail, an
- * {@link AssertionError} is thrown. Otherwise the exception is consumed by the
- * specified {@link Consumer} with no expectation on the type of the exception.
- * @param consumer the consumer of the failure
- */
- void loadAndFail(Consumer consumer);
-
- /**
- * Create and refresh a new {@link ApplicationContext} based on the current state of
- * this loader that this expected to fail. If the context does not fail, an
- * {@link AssertionError} is thrown. If the exception does not match the specified
- * {@code exceptionType}, an {@link AssertionError} is thrown as well. If the
- * exception type matches, it is consumed by the specified {@link Consumer}.
- * @param exceptionType the expected type of the failure
- * @param consumer the consumer of the failure
- * @param the expected type of the failure
- */
- void loadAndFail(Class exceptionType, Consumer consumer);
-
- /**
- * Creates a {@code ContextLoader} that will load a standard
- * {@link AnnotationConfigApplicationContext}.
- * @return the context loader
- */
- static StandardContextLoader standard() {
- return new StandardContextLoader(AnnotationConfigApplicationContext::new);
- }
-
- /**
- * Creates a {@code ContextLoader} that will load a
- * {@link AnnotationConfigWebApplicationContext}.
- * @return the context loader
- */
- static ServletWebContextLoader servletWeb() {
- return new ServletWebContextLoader(() -> {
- AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
- context.setServletContext(new MockServletContext());
- return context;
- });
- }
-
- /**
- * Creates a {@code ContextLoader} that will load a
- * {@link GenericReactiveWebApplicationContext}.
- * @return the context loader
- */
- static ReactiveWebContextLoader reactiveWeb() {
- return new ReactiveWebContextLoader(GenericReactiveWebApplicationContext::new);
- }
-
-}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebApplicationContextTester.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebApplicationContextTester.java
new file mode 100644
index 0000000000..3044d6bf6b
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebApplicationContextTester.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext;
+import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
+
+/**
+ * A {@link AbstractApplicationContextTester ApplicationContext tester} for a
+ * {@link ConfigurableReactiveWebApplicationContext}.
+ *
+ * See {@link AbstractApplicationContextTester} for details.
+ *
+ * @author Andy Wilkinson
+ * @author Stephane Nicoll
+ * @author Phillip Webb
+ * @since 2.0.0
+ */
+public final class ReactiveWebApplicationContextTester extends
+ AbstractApplicationContextTester {
+
+ /**
+ * Create a new {@link ReactiveWebApplicationContextTester} instance using a
+ * {@link GenericReactiveWebApplicationContext} as the underlying source.
+ */
+ public ReactiveWebApplicationContextTester() {
+ this(GenericReactiveWebApplicationContext::new);
+ }
+
+ /**
+ * Create a new {@link ApplicationContextTester} instance using the specified
+ * {@code contextFactory} as the underlying source.
+ * @param contextFactory a supplier that returns a new instance on each call
+ */
+ public ReactiveWebApplicationContextTester(
+ Supplier contextFactory) {
+ super(contextFactory);
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ServletWebContextLoader.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ServletWebContextLoader.java
deleted file mode 100644
index 0ce2546b3a..0000000000
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ServletWebContextLoader.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012-2017 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.boot.test.context;
-
-import java.util.function.Supplier;
-
-import org.springframework.web.context.ConfigurableWebApplicationContext;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-
-/**
- * A {@link ContextLoader} that simulates a {@link AnnotationConfigWebApplicationContext}
- * which can be useful to test components that require a servlet web application.
- *
- * @author Andy Wilkinson
- * @author Stephane Nicoll
- * @since 2.0.0
- */
-public final class ServletWebContextLoader extends
- AbstractContextLoader {
-
- ServletWebContextLoader(
- Supplier contextSupplier) {
- super(contextSupplier);
- }
-
- /**
- * Create and refresh a new {@link ConfigurableWebApplicationContext} based on the
- * current state of this loader. The context is consumed by the specified
- * {@link WebMvcContextConsumer consumer} and closed upon completion.
- * @param consumer the consumer of the created
- * {@link ConfigurableWebApplicationContext}
- */
- public void loadWeb(WebMvcContextConsumer consumer) {
- doLoad(consumer::accept);
- }
-
-}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/WebApplicationContextTester.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/WebApplicationContextTester.java
new file mode 100644
index 0000000000..98101f6e8b
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/WebApplicationContextTester.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.web.context.ConfigurableWebApplicationContext;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+
+/**
+ * A {@link AbstractApplicationContextTester ApplicationContext tester} for a Servlet
+ * based {@link ConfigurableWebApplicationContext}.
+ *
+ * See {@link AbstractApplicationContextTester} for details.
+ *
+ * @author Andy Wilkinson
+ * @author Stephane Nicoll
+ * @author Phillip Webb
+ * @since 2.0.0
+ */
+public final class WebApplicationContextTester extends
+ AbstractApplicationContextTester {
+
+ /**
+ * Create a new {@link WebApplicationContextTester} instance using an
+ * {@link AnnotationConfigWebApplicationContext} with a {@link MockServletContext} as
+ * the underlying source.
+ * @see #withMockServletContext(Supplier)
+ */
+ public WebApplicationContextTester() {
+ this(withMockServletContext(AnnotationConfigWebApplicationContext::new));
+ }
+
+ /**
+ * Create a new {@link WebApplicationContextTester} instance using the specified
+ * {@code contextFactory} as the underlying source.
+ * @param contextFactory a supplier that returns a new instance on each call
+ */
+ public WebApplicationContextTester(
+ Supplier contextFactory) {
+ super(contextFactory);
+ }
+
+ /**
+ * Decorate the specified {@code contextFactory} to set a {@link MockServletContext}
+ * on each newly created {@link WebApplicationContext}.
+ * @param contextFactory the context factory to decorate
+ * @return an updated supplier that will set the {@link MockServletContext}
+ */
+ public static Supplier withMockServletContext(
+ Supplier contextFactory) {
+ return (contextFactory == null ? null : () -> {
+ ConfigurableWebApplicationContext context = contextFactory.get();
+ context.setServletContext(new MockServletContext());
+ return context;
+ });
+ }
+
+}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractApplicationContextTesterTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractApplicationContextTesterTests.java
new file mode 100644
index 0000000000..8b49573434
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AbstractApplicationContextTesterTests.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.UUID;
+
+import com.google.gson.Gson;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.springframework.boot.context.annotation.UserConfigurations;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.util.ClassUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+/**
+ * Abstract tests for {@link AbstractApplicationContextTester} implementations.
+ *
+ * @param The tester type
+ * @param the context type
+ * @param the assertable context type
+ * @author Stephane Nicoll
+ * @author Phillip Webb
+ */
+public abstract class AbstractApplicationContextTesterTests, C extends ConfigurableApplicationContext, A extends AssertProviderApplicationContext> {
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void runWithSystemPropertiesShouldSetAndRemoveProperties() {
+ String key = "test." + UUID.randomUUID().toString();
+ assertThat(System.getProperties().containsKey(key)).isFalse();
+ get().withSystemProperties(key + "=value").run(loaded -> {
+ assertThat(System.getProperties()).containsEntry(key, "value");
+ });
+ assertThat(System.getProperties().containsKey(key)).isFalse();
+ }
+
+ @Test
+ public void runWithSystemPropertiesWhenContextFailsShouldRemoveProperties()
+ throws Exception {
+ String key = "test." + UUID.randomUUID().toString();
+ assertThat(System.getProperties().containsKey(key)).isFalse();
+ get().withSystemProperties(key + "=value")
+ .withUserConfiguration(FailingConfig.class).run(loaded -> {
+ assertThat(loaded).hasFailed();
+ });
+ assertThat(System.getProperties().containsKey(key)).isFalse();
+ }
+
+ @Test
+ public void runWithSystemPropertiesShouldRestoreOriginalProperties()
+ throws Exception {
+ String key = "test." + UUID.randomUUID().toString();
+ System.setProperty(key, "value");
+ try {
+ assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
+ get().withSystemProperties(key + "=newValue").run(loaded -> {
+ assertThat(System.getProperties()).containsEntry(key, "newValue");
+ });
+ assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
+ }
+ finally {
+ System.clearProperty(key);
+ }
+ }
+
+ @Test
+ public void runWithSystemPropertiesWhenValueIsNullShouldRemoveProperty()
+ throws Exception {
+ String key = "test." + UUID.randomUUID().toString();
+ System.setProperty(key, "value");
+ try {
+ assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
+ get().withSystemProperty(key, null).run(loaded -> {
+ assertThat(System.getProperties()).doesNotContainKey(key);
+ });
+ assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
+ }
+ finally {
+ System.clearProperty(key);
+ }
+ }
+
+ @Test
+ public void runWithMultiplePropertyValuesShouldAllAllValues() throws Exception {
+ get().withPropertyValues("test.foo=1").withPropertyValues("test.bar=2")
+ .run(loaded -> {
+ Environment environment = loaded.getEnvironment();
+ assertThat(environment.getProperty("test.foo")).isEqualTo("1");
+ assertThat(environment.getProperty("test.bar")).isEqualTo("2");
+ });
+ }
+
+ @Test
+ public void runWithPropertyValuesWhenHasExistingShouldReplaceValue()
+ throws Exception {
+ get().withPropertyValues("test.foo=1").withPropertyValues("test.foo=2")
+ .run(loaded -> {
+ Environment environment = loaded.getEnvironment();
+ assertThat(environment.getProperty("test.foo")).isEqualTo("2");
+ });
+ }
+
+ @Test
+ public void runWithConfigurationsShouldRegisterConfigurations() throws Exception {
+ get().withUserConfiguration(FooConfig.class)
+ .run((loaded) -> assertThat(loaded).hasBean("foo"));
+ }
+
+ @Test
+ public void runWithMultipleConfigurationsShouldRegisterAllConfigurations()
+ throws Exception {
+ get().withUserConfiguration(FooConfig.class)
+ .withConfiguration(UserConfigurations.of(BarConfig.class))
+ .run((loaded) -> assertThat(loaded).hasBean("foo").hasBean("bar"));
+ }
+
+ @Test
+ public void runWithFailedContextShouldReturnFailedAssertableContext()
+ throws Exception {
+ get().withUserConfiguration(FailingConfig.class)
+ .run((loaded) -> assertThat(loaded).hasFailed());
+ }
+
+ @Test
+ public void runWithClassLoaderShouldSetClassLoader() throws Exception {
+ get().withClassLoader(
+ new HidePackagesClassLoader(Gson.class.getPackage().getName()))
+ .run((loaded) -> {
+ try {
+ ClassUtils.forName(Gson.class.getName(), loaded.getClassLoader());
+ fail("Should have thrown a ClassNotFoundException");
+ }
+ catch (ClassNotFoundException e) {
+ // expected
+ }
+ });
+ }
+
+ protected abstract T get();
+
+ @Configuration
+ static class FailingConfig {
+
+ @Bean
+ public String foo() {
+ throw new IllegalStateException("Failed");
+ }
+
+ }
+
+ @Configuration
+ static class FooConfig {
+
+ @Bean
+ public String foo() {
+ return "foo";
+ }
+
+ }
+
+ @Configuration
+ static class BarConfig {
+
+ @Bean
+ public String bar() {
+ return "bar";
+ }
+
+ }
+
+}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/ApplicationContextAssertTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ApplicationContextAssertTests.java
new file mode 100644
index 0000000000..798286612b
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ApplicationContextAssertTests.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link ApplicationContextAssert}.
+ *
+ * @author Phillip Webb
+ */
+public class ApplicationContextAssertTests {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private StaticApplicationContext context = new StaticApplicationContext();
+
+ private RuntimeException failure = new RuntimeException();
+
+ @Test
+ public void createWhenApplicationContextIsNullShouldThrowException()
+ throws Exception {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("ApplicationContext must not be null");
+ new ApplicationContextAssert<>(null, null);
+ }
+
+ @Test
+ public void createWhenHasApplicationContextShouldSetActual() throws Exception {
+ assertThat(getAssert(this.context).getSourceApplicationContext())
+ .isSameAs(this.context);
+ }
+
+ @Test
+ public void createWhenHasExceptionShouldSetFailure() throws Exception {
+ assertThat(getAssert(this.failure)).getFailure().isSameAs(this.failure);
+ }
+
+ @Test
+ public void hasBeanWhenHasBeanShouldPass() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).hasBean("foo");
+ }
+
+ @Test
+ public void hasBeanWhenHasNoBeanShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("no such bean");
+ assertThat(getAssert(this.context)).hasBean("foo");
+ }
+
+ @Test
+ public void hasBeanWhenNotStartedShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).hasBean("foo");
+ }
+
+ @Test
+ public void hasSingleBeanWhenHasSingleBeanShouldPass() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).hasSingleBean(Foo.class);
+ }
+
+ @Test
+ public void hasSingleBeanWhenHasNoBeansShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("no beans of that type");
+ assertThat(getAssert(this.context)).hasSingleBean(Foo.class);
+ }
+
+ @Test
+ public void hasSingleBeanWhenHasMultipleShouldFail() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ this.context.registerSingleton("bar", Foo.class);
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("but found:");
+ assertThat(getAssert(this.context)).hasSingleBean(Foo.class);
+ }
+
+ @Test
+ public void hasSingleBeanWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).hasSingleBean(Foo.class);
+ }
+
+ @Test
+ public void doesNotHaveBeanOfTypeWhenHasNoBeanOfTypeShouldPass() throws Exception {
+ assertThat(getAssert(this.context)).doesNotHaveBean(Foo.class);
+ }
+
+ @Test
+ public void doesNotHaveBeanOfTypeWhenHasBeanOfTypeShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("but found");
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).doesNotHaveBean(Foo.class);
+ }
+
+ @Test
+ public void doesNotHaveBeanOfTypeWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).doesNotHaveBean(Foo.class);
+ }
+
+ @Test
+ public void doesNotHaveBeanOfNameWhenHasNoBeanOfTypeShouldPass() throws Exception {
+ assertThat(getAssert(this.context)).doesNotHaveBean("foo");
+ }
+
+ @Test
+ public void doesNotHaveBeanOfNameWhenHasBeanOfTypeShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("but found");
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).doesNotHaveBean("foo");
+ }
+
+ @Test
+ public void doesNotHaveBeanOfNameWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).doesNotHaveBean("foo");
+ }
+
+ @Test
+ public void getBeanNamesWhenHasNamesShouldReturnNamesAssert() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ this.context.registerSingleton("bar", Foo.class);
+ assertThat(getAssert(this.context)).getBeanNames(Foo.class).containsOnly("foo",
+ "bar");
+ }
+
+ @Test
+ public void getBeanNamesWhenHasNoNamesShouldReturnEmptyAssert() throws Exception {
+ assertThat(getAssert(this.context)).getBeanNames(Foo.class).isEmpty();
+ }
+
+ @Test
+ public void getBeanNamesWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).doesNotHaveBean("foo");
+ }
+
+ @Test
+ public void getBeanOfTypeWhenHasBeanShouldReturnBeanAssert() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).getBean(Foo.class).isNotNull();
+ }
+
+ @Test
+ public void getBeanOfTypeWhenHasNoBeanShouldReturnNullAssert() throws Exception {
+ assertThat(getAssert(this.context)).getBean(Foo.class).isNull();
+ }
+
+ @Test
+ public void getBeanOfTypeWhenHasMultipleBeansShouldFail() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ this.context.registerSingleton("bar", Foo.class);
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("but found");
+ assertThat(getAssert(this.context)).getBean(Foo.class);
+ }
+
+ @Test
+ public void getBeanOfTypeWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).getBean(Foo.class);
+ }
+
+ @Test
+ public void getBeanOfNameWhenHasBeanShouldReturnBeanAssert() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).getBean("foo").isNotNull();
+ }
+
+ @Test
+ public void getBeanOfNameWhenHasNoBeanOfNameShouldReturnNullAssert()
+ throws Exception {
+ assertThat(getAssert(this.context)).getBean("foo").isNull();
+ }
+
+ @Test
+ public void getBeanOfNameWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).getBean("foo");
+ }
+
+ @Test
+ public void getBeanOfNameAndTypeWhenHasBeanShouldReturnBeanAssert() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ assertThat(getAssert(this.context)).getBean("foo", Foo.class).isNotNull();
+ }
+
+ @Test
+ public void getBeanOfNameAndTypeWhenHasNoBeanOfNameShouldReturnNullAssert()
+ throws Exception {
+ assertThat(getAssert(this.context)).getBean("foo", Foo.class).isNull();
+ }
+
+ @Test
+ public void getBeanOfNameAndTypeWhenHasNoBeanOfNameButDifferentTypeShouldFail()
+ throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("of type");
+ assertThat(getAssert(this.context)).getBean("foo", String.class);
+ }
+
+ @Test
+ public void getBeanOfNameAndTypeWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).getBean("foo", Foo.class);
+ }
+
+ @Test
+ public void getBeansWhenHasBeansShouldReturnMapAssert() throws Exception {
+ this.context.registerSingleton("foo", Foo.class);
+ this.context.registerSingleton("bar", Foo.class);
+ assertThat(getAssert(this.context)).getBeans(Foo.class).hasSize(2)
+ .containsKeys("foo", "bar");
+ }
+
+ @Test
+ public void getBeansWhenHasNoBeansShouldReturnEmptyMapAssert() throws Exception {
+ assertThat(getAssert(this.context)).getBeans(Foo.class).isEmpty();
+ }
+
+ @Test
+ public void getBeansWhenFailedToStartShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("failed to start");
+ assertThat(getAssert(this.failure)).getBeans(Foo.class);
+ }
+
+ @Test
+ public void getFailureWhenFailedShouldReturnFailure() throws Exception {
+ assertThat(getAssert(this.failure)).getFailure().isSameAs(this.failure);
+ }
+
+ @Test
+ public void getFailureWhenDidNotFailShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("context started");
+ assertThat(getAssert(this.context)).getFailure();
+ }
+
+ @Test
+ public void hasFailedWhenFailedShouldPass() throws Exception {
+ assertThat(getAssert(this.failure)).hasFailed();
+ }
+
+ @Test
+ public void hasFailedWhenNotFailedShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("to have failed");
+ assertThat(getAssert(this.context)).hasFailed();
+ }
+
+ @Test
+ public void hasNotFailedWhenFailedShouldFail() throws Exception {
+ this.thrown.expect(AssertionError.class);
+ this.thrown.expectMessage("to have not failed");
+ assertThat(getAssert(this.failure)).hasNotFailed();
+ }
+
+ @Test
+ public void hasNotFailedWhenNotFailedShouldPass() throws Exception {
+ assertThat(getAssert(this.context)).hasNotFailed();
+ }
+
+ private AssertableApplicationContext getAssert(
+ ConfigurableApplicationContext applicationContext) {
+ return AssertableApplicationContext.get(() -> applicationContext);
+ }
+
+ private AssertableApplicationContext getAssert(RuntimeException failure) {
+ return AssertableApplicationContext.get(() -> {
+ throw failure;
+ });
+ }
+
+ private static class Foo {
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/StandardContextLoader.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ApplicationContextTesterTests.java
similarity index 59%
rename from spring-boot-test/src/main/java/org/springframework/boot/test/context/StandardContextLoader.java
rename to spring-boot-test/src/test/java/org/springframework/boot/test/context/ApplicationContextTesterTests.java
index a58fa9f75a..01c5f1e3b3 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/StandardContextLoader.java
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ApplicationContextTesterTests.java
@@ -16,23 +16,20 @@
package org.springframework.boot.test.context;
-import java.util.function.Supplier;
-
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
- * A {@link ContextLoader} that simulates a standard, non web environment.
+ * Tests for {@link ApplicationContextTester}.
*
* @author Stephane Nicoll
- * @author Andy Wilkinson
- * @since 2.0.0
+ * @author Phillip Webb
*/
-public class StandardContextLoader extends
- AbstractContextLoader {
+public class ApplicationContextTesterTests extends
+ AbstractApplicationContextTesterTests {
- public StandardContextLoader(
- Supplier contextSupplier) {
- super(contextSupplier);
+ @Override
+ protected ApplicationContextTester get() {
+ return new ApplicationContextTester();
}
}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertProviderApplicationContextTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertProviderApplicationContextTests.java
new file mode 100644
index 0000000000..5d5cdad937
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertProviderApplicationContextTests.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import java.util.function.Supplier;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Tests for {@link AssertProviderApplicationContext} and
+ * {@link AssertProviderApplicationContextInvocationHandler}.
+ *
+ * @author Phillip Webb
+ */
+public class AssertProviderApplicationContextTests {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Mock
+ private ConfigurableApplicationContext mockContext;
+
+ private RuntimeException startupFailure;
+
+ private Supplier mockContextSupplier;
+
+ private Supplier startupFailureSupplier;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ this.startupFailure = new RuntimeException();
+ this.mockContextSupplier = () -> this.mockContext;
+ this.startupFailureSupplier = () -> {
+ throw this.startupFailure;
+ };
+ }
+
+ @Test
+ public void getWhenTypeIsNullShouldThrowExecption() throws Exception {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("Type must not be null");
+ AssertProviderApplicationContext.get(null, ApplicationContext.class,
+ this.mockContextSupplier);
+ }
+
+ @Test
+ public void getWhenTypeIsClassShouldThrowException() throws Exception {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("Type must not be null");
+ AssertProviderApplicationContext.get(null, ApplicationContext.class,
+ this.mockContextSupplier);
+ }
+
+ @Test
+ public void getWhenContextTypeIsNullShouldThrowException() throws Exception {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("Type must be an interface");
+ AssertProviderApplicationContext.get(
+ TestAssertProviderApplicationContextClass.class, ApplicationContext.class,
+ this.mockContextSupplier);
+ }
+
+ @Test
+ public void getWhenContextTypeIsClassShouldThrowException() throws Exception {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("ContextType must not be null");
+ AssertProviderApplicationContext.get(TestAssertProviderApplicationContext.class,
+ null, this.mockContextSupplier);
+ }
+
+ @Test
+ public void getWhenSupplierIsNullShouldThrowException() throws Exception {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("ContextType must be an interface");
+ AssertProviderApplicationContext.get(TestAssertProviderApplicationContext.class,
+ StaticApplicationContext.class, this.mockContextSupplier);
+ }
+
+ @Test
+ public void getWhenContextStartsShouldReturnProxyThatCallsRealMethods()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ assertThat((Object) context).isNotNull();
+ context.getBean("foo");
+ verify(this.mockContext).getBean("foo");
+ }
+
+ @Test
+ public void getWhenContextFailsShouldReturnProxyThatThrowsExceptions()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.startupFailureSupplier);
+ assertThat((Object) context).isNotNull();
+ expectStartupFailure();
+ context.getBean("foo");
+ }
+
+ @Test
+ public void getSourceContextWhenContextStartsShouldReturnSourceContext()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ assertThat(context.getSourceApplicationContext()).isSameAs(this.mockContext);
+ }
+
+ @Test
+ public void getSourceContextWhenContextFailsShouldThrowException() throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.startupFailureSupplier);
+ expectStartupFailure();
+ context.getSourceApplicationContext();
+ }
+
+ @Test
+ public void getSourceContextOfTypeWhenContextStartsShouldReturnSourceContext()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ assertThat(context.getSourceApplicationContext(ApplicationContext.class))
+ .isSameAs(this.mockContext);
+ }
+
+ @Test
+ public void getSourceContextOfTypeWhenContextFailsToStartShouldThrowException()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.startupFailureSupplier);
+ expectStartupFailure();
+ context.getSourceApplicationContext(ApplicationContext.class);
+ }
+
+ @Test
+ public void getStartupFailureWhenContextStartsShouldReturnNull() throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ assertThat(context.getStartupFailure()).isNull();
+ }
+
+ @Test
+ public void getStartupFailureWhenContextFailsToStartShouldReturnException()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.startupFailureSupplier);
+ assertThat(context.getStartupFailure()).isEqualTo(this.startupFailure);
+ }
+
+ @Test
+ public void assertThatWhenContextStartsShouldReturnAssertions() throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ ApplicationContextAssert contextAssert = assertThat(context);
+ assertThat(contextAssert.getApplicationContext()).isSameAs(context);
+ assertThat(contextAssert.getStartupFailure()).isNull();
+ }
+
+ @Test
+ public void assertThatWhenContextFailsShouldReturnAssertions() throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.startupFailureSupplier);
+ ApplicationContextAssert contextAssert = assertThat(context);
+ assertThat(contextAssert.getApplicationContext()).isSameAs(context);
+ assertThat(contextAssert.getStartupFailure()).isSameAs(this.startupFailure);
+ }
+
+ @Test
+ public void toStringWhenContextStartsShouldReturnSimpleString() throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ assertThat(context.toString())
+ .startsWith(
+ "Started application org.springframework.context.ConfigurableApplicationContext$MockitoMock")
+ .endsWith("[id=,applicationName=,beanDefinitionCount=0]");
+ }
+
+ @Test
+ public void toStringWhenContextFailsToStartShouldReturnSimpleString()
+ throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.startupFailureSupplier);
+ assertThat(context.toString()).isEqualTo("Unstarted application context "
+ + "org.springframework.context.ApplicationContext"
+ + "[startupFailure=java.lang.RuntimeException]");
+ }
+
+ @Test
+ public void closeShouldCloseContext() throws Exception {
+ AssertProviderApplicationContext context = get(
+ this.mockContextSupplier);
+ context.close();
+ verify(this.mockContext).close();
+ }
+
+ private void expectStartupFailure() {
+ this.thrown.expect(IllegalStateException.class);
+ this.thrown.expectMessage("failed to start");
+ this.thrown.expectCause(equalTo(this.startupFailure));
+ }
+
+ private AssertProviderApplicationContext get(
+ Supplier contextSupplier) {
+ return AssertProviderApplicationContext.get(
+ TestAssertProviderApplicationContext.class, ApplicationContext.class,
+ contextSupplier);
+ }
+
+ private interface TestAssertProviderApplicationContext
+ extends AssertProviderApplicationContext {
+
+ }
+
+ private abstract static class TestAssertProviderApplicationContextClass
+ implements TestAssertProviderApplicationContext {
+
+ }
+
+}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableApplicationContextTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableApplicationContextTests.java
new file mode 100644
index 0000000000..9d1e4a7ca0
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableApplicationContextTests.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import org.junit.Test;
+
+import org.springframework.context.ConfigurableApplicationContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link AssertableApplicationContext}.
+ *
+ * @author Phillip Webb
+ * @see AssertProviderApplicationContextTests
+ */
+public class AssertableApplicationContextTests {
+
+ @Test
+ public void getShouldReturnProxy() {
+ AssertableApplicationContext context = AssertableApplicationContext
+ .get(() -> mock(ConfigurableApplicationContext.class));
+ assertThat(context).isInstanceOf(ConfigurableApplicationContext.class);
+ }
+
+}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableReactiveWebApplicationContextTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableReactiveWebApplicationContextTests.java
new file mode 100644
index 0000000000..4f5b49196d
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableReactiveWebApplicationContextTests.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import org.junit.Test;
+
+import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link AssertableReactiveWebApplicationContext}.
+ *
+ * @author Phillip Webb
+ * @see AssertProviderApplicationContextTests
+ */
+public class AssertableReactiveWebApplicationContextTests {
+
+ @Test
+ public void getShouldReturnProxy() {
+ AssertableReactiveWebApplicationContext context = AssertableReactiveWebApplicationContext
+ .get(() -> mock(ConfigurableReactiveWebApplicationContext.class));
+ assertThat(context).isInstanceOf(ConfigurableReactiveWebApplicationContext.class);
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/WebMvcContextConsumer.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableWebApplicationContextTests.java
similarity index 57%
rename from spring-boot-test/src/main/java/org/springframework/boot/test/context/WebMvcContextConsumer.java
rename to spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableWebApplicationContextTests.java
index b982a0533d..b49effc0a9 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/WebMvcContextConsumer.java
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/AssertableWebApplicationContextTests.java
@@ -16,25 +16,26 @@
package org.springframework.boot.test.context;
+import org.junit.Test;
+
import org.springframework.web.context.ConfigurableWebApplicationContext;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
/**
- * Specialized callback interface used in tests to process a running
- * {@link ConfigurableWebApplicationContext} with the ability to throw a (checked)
- * exception.
+ * Tests for {@link AssertableWebApplicationContext}.
*
- * @author Stephane Nicoll
- * @see ContextConsumer
- * @since 2.0.0
+ * @author Phillip Webb
+ * @see AssertProviderApplicationContextTests
*/
-@FunctionalInterface
-public interface WebMvcContextConsumer {
+public class AssertableWebApplicationContextTests {
- /**
- * Performs this operation on the supplied {@code context}.
- * @param context the application context to consume
- * @throws Throwable any exception that might occur in assertions
- */
- void accept(ConfigurableWebApplicationContext context) throws Throwable;
+ @Test
+ public void getShouldReturnProxy() {
+ AssertableWebApplicationContext context = AssertableWebApplicationContext
+ .get(() -> mock(ConfigurableWebApplicationContext.class));
+ assertThat(context).isInstanceOf(ConfigurableWebApplicationContext.class);
+ }
}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebContextLoader.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ReactiveWebApplicationContextTesterTests.java
similarity index 54%
rename from spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebContextLoader.java
rename to spring-boot-test/src/test/java/org/springframework/boot/test/context/ReactiveWebApplicationContextTesterTests.java
index 77d671d8bc..6a7d7753f4 100644
--- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ReactiveWebContextLoader.java
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ReactiveWebApplicationContextTesterTests.java
@@ -16,24 +16,20 @@
package org.springframework.boot.test.context;
-import java.util.function.Supplier;
-
-import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
+import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext;
/**
- * A {@link ContextLoader} that simulates a {@link GenericReactiveWebApplicationContext}
- * which can be useful to test components that require a reactive web application.
+ * Tests for {@link ReactiveWebApplicationContextTester}.
*
- * @author Andy Wilkinson
* @author Stephane Nicoll
- * @since 2.0.0
+ * @author Phillip Webb
*/
-public final class ReactiveWebContextLoader extends
- AbstractContextLoader {
+public class ReactiveWebApplicationContextTesterTests extends
+ AbstractApplicationContextTesterTests {
- ReactiveWebContextLoader(
- Supplier contextSupplier) {
- super(contextSupplier);
+ @Override
+ protected ReactiveWebApplicationContextTester get() {
+ return new ReactiveWebApplicationContextTester();
}
}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/StandardContextLoaderTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/StandardContextLoaderTests.java
deleted file mode 100644
index bd91cf6e4b..0000000000
--- a/spring-boot-test/src/test/java/org/springframework/boot/test/context/StandardContextLoaderTests.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright 2012-2017 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.boot.test.context;
-
-import java.util.UUID;
-
-import com.google.gson.Gson;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.util.ClassUtils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-/**
- * Tests for {@link StandardContextLoader}.
- *
- * @author Stephane Nicoll
- */
-public class StandardContextLoaderTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none();
-
- private final StandardContextLoader contextLoader = new StandardContextLoader(
- AnnotationConfigApplicationContext::new);
-
- @Test
- public void systemPropertyIsSetAndRemoved() {
- String key = "test." + UUID.randomUUID().toString();
- assertThat(System.getProperties().containsKey(key)).isFalse();
- this.contextLoader.systemProperty(key, "value").load(context -> {
- assertThat(System.getProperties().containsKey(key)).isTrue();
- assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
- });
- assertThat(System.getProperties().containsKey(key)).isFalse();
- }
-
- @Test
- public void systemPropertyIsRemovedIfContextFailed() {
- String key = "test." + UUID.randomUUID().toString();
- assertThat(System.getProperties().containsKey(key)).isFalse();
- this.contextLoader.systemProperty(key, "value").config(ConfigC.class)
- .loadAndFail(e -> {
- });
- assertThat(System.getProperties().containsKey(key)).isFalse();
- }
-
- @Test
- public void systemPropertyIsRestoredToItsOriginalValue() {
- String key = "test." + UUID.randomUUID().toString();
- System.setProperty(key, "value");
- try {
- assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
- this.contextLoader.systemProperty(key, "newValue").load(context -> {
- assertThat(System.getProperties().getProperty(key)).isEqualTo("newValue");
- });
- assertThat(System.getProperties().getProperty(key)).isEqualTo("value");
- }
- finally {
- System.clearProperty(key);
- }
- }
-
- @Test
- public void systemPropertyCanBeSetToNullValue() {
- String key = "test." + UUID.randomUUID().toString();
- assertThat(System.getProperties().containsKey(key)).isFalse();
- this.contextLoader.systemProperty(key, "value").systemProperty(key, null)
- .load(context -> {
- assertThat(System.getProperties().containsKey(key)).isFalse();
- });
- }
-
- @Test
- public void systemPropertyNeedNonNullKey() {
- this.thrown.expect(IllegalArgumentException.class);
- this.contextLoader.systemProperty(null, "value");
- }
-
- @Test
- public void envIsAdditive() {
- this.contextLoader.env("test.foo=1").env("test.bar=2").load(context -> {
- ConfigurableEnvironment environment = context
- .getBean(ConfigurableEnvironment.class);
- assertThat(environment.getProperty("test.foo", Integer.class)).isEqualTo(1);
- assertThat(environment.getProperty("test.bar", Integer.class)).isEqualTo(2);
- });
- }
-
- @Test
- public void envOverridesExistingKey() {
- this.contextLoader.env("test.foo=1").env("test.foo=2")
- .load(context -> assertThat(context.getBean(ConfigurableEnvironment.class)
- .getProperty("test.foo", Integer.class)).isEqualTo(2));
- }
-
- @Test
- public void configurationIsProcessedInOrder() {
- this.contextLoader.config(ConfigA.class, AutoConfigA.class).load(
- context -> assertThat(context.getBean("a")).isEqualTo("autoconfig-a"));
- }
-
- @Test
- public void configurationIsProcessedBeforeAutoConfiguration() {
- this.contextLoader.autoConfig(AutoConfigA.class).config(ConfigA.class).load(
- context -> assertThat(context.getBean("a")).isEqualTo("autoconfig-a"));
- }
-
- @Test
- public void configurationIsAdditive() {
- this.contextLoader.config(AutoConfigA.class).config(AutoConfigB.class)
- .load(context -> {
- assertThat(context.containsBean("a")).isTrue();
- assertThat(context.containsBean("b")).isTrue();
- });
- }
-
- @Test
- public void autoConfigureFirstIsAppliedProperly() {
- this.contextLoader.autoConfig(ConfigA.class).autoConfigFirst(AutoConfigA.class)
- .load(context -> assertThat(context.getBean("a")).isEqualTo("a"));
- }
-
- @Test
- public void autoConfigureFirstWithSeveralConfigsIsAppliedProperly() {
- this.contextLoader.autoConfig(ConfigA.class, ConfigB.class)
- .autoConfigFirst(AutoConfigA.class, AutoConfigB.class).load(context -> {
- assertThat(context.getBean("a")).isEqualTo("a");
- assertThat(context.getBean("b")).isEqualTo(1);
- });
- }
-
- @Test
- public void autoConfigurationIsAdditive() {
- this.contextLoader.autoConfig(AutoConfigA.class).autoConfig(AutoConfigB.class)
- .load(context -> {
- assertThat(context.containsBean("a")).isTrue();
- assertThat(context.containsBean("b")).isTrue();
- });
- }
-
- @Test
- public void loadAndFailWithExpectedException() {
- this.contextLoader.config(ConfigC.class).loadAndFail(BeanCreationException.class,
- ex -> assertThat(ex.getMessage())
- .contains("Error creating bean with name 'c'"));
- }
-
- @Test
- public void loadAndFailWithWrongException() {
- this.thrown.expect(AssertionError.class);
- this.thrown.expectMessage("Wrong application context failure exception");
- this.contextLoader.config(ConfigC.class)
- .loadAndFail(IllegalArgumentException.class, ex -> {
- });
- }
-
- @Test
- public void classLoaderIsUsed() {
- this.contextLoader
- .classLoader(
- new HidePackagesClassLoader(Gson.class.getPackage().getName()))
- .load(context -> {
- try {
- ClassUtils.forName(Gson.class.getName(),
- context.getClassLoader());
- fail("Should have thrown a ClassNotFoundException");
- }
- catch (ClassNotFoundException e) {
- // expected
- }
- });
- }
-
- @Test
- public void assertionErrorsAreAvailableAsIs() {
- try {
- this.contextLoader.load(context -> {
- fail("This is expected");
- });
- }
- catch (AssertionError ex) {
- assertThat(ex.getMessage()).isEqualTo("This is expected");
- }
- }
-
- @Configuration
- static class ConfigA {
-
- @Bean
- public String a() {
- return "a";
- }
-
- }
-
- @Configuration
- static class ConfigB {
-
- @Bean
- public Integer b() {
- return 1;
- }
-
- }
-
- @Configuration
- static class AutoConfigA {
-
- @Bean
- public String a() {
- return "autoconfig-a";
- }
-
- }
-
- @Configuration
- static class AutoConfigB {
-
- @Bean
- public Integer b() {
- return 42;
- }
-
- }
-
- @Configuration
- static class ConfigC {
-
- @Bean
- public String c(Integer value) {
- return String.valueOf(value);
- }
- }
-
-}
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/WebApplicationContextTesterTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/WebApplicationContextTesterTests.java
new file mode 100644
index 0000000000..4b37ec6345
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/WebApplicationContextTesterTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012-2017 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.boot.test.context;
+
+import org.junit.Test;
+
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.web.context.ConfigurableWebApplicationContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link WebApplicationContextTester}.
+ *
+ * @author Stephane Nicoll
+ * @author Phillip Webb
+ */
+public class WebApplicationContextTesterTests extends
+ AbstractApplicationContextTesterTests {
+
+ @Test
+ public void contextShouldHaveMockServletContext() throws Exception {
+ get().run((loaded) -> assertThat(loaded.getServletContext())
+ .isInstanceOf(MockServletContext.class));
+ }
+
+ @Override
+ protected WebApplicationContextTester get() {
+ return new WebApplicationContextTester();
+ }
+
+}