001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.test.context.runner;
018
019import java.util.List;
020import java.util.function.Supplier;
021
022import org.springframework.boot.context.annotation.Configurations;
023import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
024import org.springframework.boot.test.util.TestPropertyValues;
025import org.springframework.context.ApplicationContext;
026import org.springframework.context.ApplicationContextInitializer;
027import org.springframework.mock.web.MockServletContext;
028import org.springframework.web.context.ConfigurableWebApplicationContext;
029import org.springframework.web.context.WebApplicationContext;
030import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
031
032/**
033 * An {@link AbstractApplicationContextRunner ApplicationContext runner} for a Servlet
034 * based {@link ConfigurableWebApplicationContext}.
035 * <p>
036 * See {@link AbstractApplicationContextRunner} for details.
037 *
038 * @author Andy Wilkinson
039 * @author Stephane Nicoll
040 * @author Phillip Webb
041 * @since 2.0.0
042 */
043public final class WebApplicationContextRunner extends
044                AbstractApplicationContextRunner<WebApplicationContextRunner, ConfigurableWebApplicationContext, AssertableWebApplicationContext> {
045
046        /**
047         * Create a new {@link WebApplicationContextRunner} instance using an
048         * {@link AnnotationConfigWebApplicationContext} with a {@link MockServletContext} as
049         * the underlying source.
050         * @see #withMockServletContext(Supplier)
051         */
052        public WebApplicationContextRunner() {
053                this(withMockServletContext(AnnotationConfigWebApplicationContext::new));
054        }
055
056        /**
057         * Create a new {@link WebApplicationContextRunner} instance using the specified
058         * {@code contextFactory} as the underlying source.
059         * @param contextFactory a supplier that returns a new instance on each call
060         */
061        public WebApplicationContextRunner(
062                        Supplier<ConfigurableWebApplicationContext> contextFactory) {
063                super(contextFactory);
064        }
065
066        private WebApplicationContextRunner(
067                        Supplier<ConfigurableWebApplicationContext> contextFactory,
068                        List<ApplicationContextInitializer<? super ConfigurableWebApplicationContext>> initializers,
069                        TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
070                        ClassLoader classLoader, ApplicationContext parent,
071                        List<Configurations> configurations) {
072                super(contextFactory, initializers, environmentProperties, systemProperties,
073                                classLoader, parent, configurations);
074        }
075
076        @Override
077        protected WebApplicationContextRunner newInstance(
078                        Supplier<ConfigurableWebApplicationContext> contextFactory,
079                        List<ApplicationContextInitializer<? super ConfigurableWebApplicationContext>> initializers,
080                        TestPropertyValues environmentProperties, TestPropertyValues systemProperties,
081                        ClassLoader classLoader, ApplicationContext parent,
082                        List<Configurations> configurations) {
083                return new WebApplicationContextRunner(contextFactory, initializers,
084                                environmentProperties, systemProperties, classLoader, parent,
085                                configurations);
086        }
087
088        /**
089         * Decorate the specified {@code contextFactory} to set a {@link MockServletContext}
090         * on each newly created {@link WebApplicationContext}.
091         * @param contextFactory the context factory to decorate
092         * @return an updated supplier that will set the {@link MockServletContext}
093         */
094        public static Supplier<ConfigurableWebApplicationContext> withMockServletContext(
095                        Supplier<ConfigurableWebApplicationContext> contextFactory) {
096                return (contextFactory != null) ? () -> {
097                        ConfigurableWebApplicationContext context = contextFactory.get();
098                        context.setServletContext(new MockServletContext());
099                        return context;
100                } : null;
101        }
102
103}