Add support for Mock test with WebFlux
This commit add mock support for WebFlux with an infrastructure similar to what `WebMvcTest` provides. `@WebFluxTest` can be used to test controllers with a narrowed classpath that is relevant to WebFlux. Also, `@SpringBootTest` now starts WebFlux in "mock" mode by default and `@AutoConfigureWebTestClient` can be used to inject a `WebTestClient` connected to the `ApplicationContext`. To make that happen, a `ReactiveWebApplicationContext` interface has been introduced to mirror what `WebApplicationContext` currently does. Things are still a bit volatile at this point and that infra may move to Spring Framework at some point. Closes gh-8401pull/8198/merge
parent
30564eb619
commit
c5595f296c
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
|
||||
/**
|
||||
* {@link ImportAutoConfiguration Auto-configuration imports} for typical Spring WebFlux
|
||||
* tests. Most tests should consider using {@link WebFluxTest @WebFluxTest} rather than
|
||||
* using this annotation directly.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
* @see WebFluxTest
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@ImportAutoConfiguration
|
||||
public @interface AutoConfigureWebFlux {
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* Annotation that can be applied to a test class to enable a {@link WebTestClient}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
* @see WebTestClientAutoConfiguration
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@ImportAutoConfiguration
|
||||
public @interface AutoConfigureWebTestClient {
|
||||
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
|
||||
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.test.context.BootstrapWith;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)}
|
||||
* for a typical Spring WebFlux test. Can be used when a test focuses
|
||||
* <strong>only</strong> on Spring WebFlux components.
|
||||
* <p>
|
||||
* Using this annotation will disable full auto-configuration and instead apply only
|
||||
* configuration relevant to WebFlux tests (i.e. {@code @Controller},
|
||||
* {@code @ControllerAdvice}, {@code @JsonComponent} and {@code WebFluxConfigurer} beans
|
||||
* but not {@code @Component}, {@code @Service} or {@code @Repository} beans).
|
||||
* <p>
|
||||
* By default, tests annotated with {@code @WebFluxTest} will also auto-configure a
|
||||
* {@link WebTestClient}. For more fine-grained control of WebTestClient the
|
||||
* {@link AutoConfigureWebTestClient @AutoConfigureWebTestClient} annotation can be used.
|
||||
* <p>
|
||||
* Typically {@code @WebFluxTest} is used in combination with {@link MockBean @MockBean} or
|
||||
* {@link Import @Import} to create any collaborators required by your {@code @Controller}
|
||||
* beans.
|
||||
* <p>
|
||||
* If you are looking to load your full application configuration and use WebTestClient,
|
||||
* you should consider {@link SpringBootTest @SpringBootTest} combined with
|
||||
* {@link AutoConfigureWebTestClient @AutoConfigureWebTestClient} rather than this
|
||||
* annotation.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
* @see AutoConfigureWebFlux
|
||||
* @see AutoConfigureWebTestClient
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@BootstrapWith(WebFluxTestContextBootstrapper.class)
|
||||
@OverrideAutoConfiguration(enabled = false)
|
||||
@TypeExcludeFilters(WebFluxTypeExcludeFilter.class)
|
||||
@AutoConfigureCache
|
||||
@AutoConfigureWebFlux
|
||||
@AutoConfigureWebTestClient
|
||||
@ImportAutoConfiguration
|
||||
public @interface WebFluxTest {
|
||||
|
||||
/**
|
||||
* Specifies the controllers to test. This is an alias of {@link #controllers()} which
|
||||
* can be used for brevity if no other attributes are defined. See
|
||||
* {@link #controllers()} for details.
|
||||
* @see #controllers()
|
||||
* @return the controllers to test
|
||||
*/
|
||||
@AliasFor("controllers")
|
||||
Class<?>[] value() default {};
|
||||
|
||||
/**
|
||||
* Specifies the controllers to test. May be left blank if all {@code @Controller}
|
||||
* beans should be added to the application context.
|
||||
* @see #value()
|
||||
* @return the controllers to test
|
||||
*/
|
||||
@AliasFor("value")
|
||||
Class<?>[] controllers() default {};
|
||||
|
||||
/**
|
||||
* Determines if default filtering should be used with
|
||||
* {@link SpringBootApplication @SpringBootApplication}. By default only
|
||||
* {@code @Controller} (when no explicit {@link #controllers() controllers} are
|
||||
* defined), {@code @ControllerAdvice} and {@code WebFluxConfigurer} beans are
|
||||
* included.
|
||||
* @see #includeFilters()
|
||||
* @see #excludeFilters()
|
||||
* @return if default filters should be used
|
||||
*/
|
||||
boolean useDefaultFilters() default true;
|
||||
|
||||
/**
|
||||
* A set of include filters which can be used to add otherwise filtered beans to the
|
||||
* application context.
|
||||
* @return include filters to apply
|
||||
*/
|
||||
ComponentScan.Filter[] includeFilters() default {};
|
||||
|
||||
/**
|
||||
* A set of exclude filters which can be used to filter beans that would otherwise be
|
||||
* added to the application context.
|
||||
* @return exclude filters to apply
|
||||
*/
|
||||
ComponentScan.Filter[] excludeFilters() default {};
|
||||
|
||||
/**
|
||||
* Auto-configuration exclusions that should be applied for this test.
|
||||
* @return auto-configuration exclusions to apply
|
||||
*/
|
||||
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
|
||||
Class<?>[] excludeAutoConfiguration() default {};
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import org.springframework.boot.test.context.ReactiveWebMergedContextConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.test.context.TestContextBootstrapper;
|
||||
|
||||
/**
|
||||
* {@link TestContextBootstrapper} for {@link WebFluxTest @WebFluxTest} support.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class WebFluxTestContextBootstrapper extends SpringBootTestContextBootstrapper {
|
||||
|
||||
@Override
|
||||
protected MergedContextConfiguration processMergedContextConfiguration(
|
||||
MergedContextConfiguration mergedConfig) {
|
||||
return new ReactiveWebMergedContextConfiguration(
|
||||
super.processMergedContextConfiguration(mergedConfig));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.TypeExcludeFilter;
|
||||
import org.springframework.boot.jackson.JsonComponent;
|
||||
import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
|
||||
/**
|
||||
* {@link TypeExcludeFilter} for {@link WebFluxTest @WebFluxTest}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class WebFluxTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
|
||||
|
||||
private static final Set<Class<?>> DEFAULT_INCLUDES;
|
||||
|
||||
static {
|
||||
Set<Class<?>> includes = new LinkedHashSet<Class<?>>();
|
||||
includes.add(ControllerAdvice.class);
|
||||
includes.add(JsonComponent.class);
|
||||
includes.add(WebFluxConfigurer.class);
|
||||
DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
|
||||
}
|
||||
|
||||
private static final Set<Class<?>> DEFAULT_INCLUDES_AND_CONTROLLER;
|
||||
|
||||
static {
|
||||
Set<Class<?>> includes = new LinkedHashSet<Class<?>>(DEFAULT_INCLUDES);
|
||||
includes.add(Controller.class);
|
||||
DEFAULT_INCLUDES_AND_CONTROLLER = Collections.unmodifiableSet(includes);
|
||||
}
|
||||
|
||||
private final WebFluxTest annotation;
|
||||
|
||||
WebFluxTypeExcludeFilter(Class<?> testClass) {
|
||||
this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
|
||||
WebFluxTest.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasAnnotation() {
|
||||
return this.annotation != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComponentScan.Filter[] getFilters(FilterType type) {
|
||||
switch (type) {
|
||||
case INCLUDE:
|
||||
return this.annotation.includeFilters();
|
||||
case EXCLUDE:
|
||||
return this.annotation.excludeFilters();
|
||||
}
|
||||
throw new IllegalStateException("Unsupported type " + type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isUseDefaultFilters() {
|
||||
return this.annotation.useDefaultFilters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getDefaultIncludes() {
|
||||
if (ObjectUtils.isEmpty(this.annotation.controllers())) {
|
||||
return DEFAULT_INCLUDES_AND_CONTROLLER;
|
||||
}
|
||||
return DEFAULT_INCLUDES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getComponentIncludes() {
|
||||
return new LinkedHashSet<>(Arrays.asList(this.annotation.controllers()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Auto-configuration for {@link WebTestClient}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ WebClient.class, WebTestClient.class })
|
||||
public class WebTestClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WebTestClient webTestClient(ApplicationContext applicationContext) {
|
||||
return WebTestClient.bindToApplicationContext(applicationContext).build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Example {@link Controller} used with {@link WebFluxTest} tests.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RestController
|
||||
public class ExampleController1 {
|
||||
|
||||
@GetMapping("/one")
|
||||
public Mono<String> one() {
|
||||
return Mono.just("one");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Example {@link Controller} used with {@link WebFluxTest} tests.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RestController
|
||||
public class ExampleController2 {
|
||||
|
||||
@GetMapping("/two")
|
||||
public Mono<String> two() {
|
||||
return Mono.just("two");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* Example {@link Service} used with {@link WebFluxTest} tests.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Service
|
||||
public class ExampleRealService {
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* Example {@link SpringBootApplication} used with {@link WebFluxTest} tests.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ExampleWebFluxApplication {
|
||||
}
|
@ -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.autoconfigure.web.reactive;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebFluxTest} when no explicit controller is defined.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebFluxTest
|
||||
public class WebFluxTestAllControllersIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Test
|
||||
public void shouldFindController1() {
|
||||
this.webClient
|
||||
.get().uri("/one")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindController2() {
|
||||
this.webClient
|
||||
.get().uri("/two")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("two");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.importedAutoConfiguration;
|
||||
|
||||
/**
|
||||
* Tests for the auto-configuration imported by {@link WebFluxTest}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebFluxTest
|
||||
public class WebFluxTestAutoConfigurationIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void messageSourceAutoConfigurationIsImported() {
|
||||
assertThat(this.applicationContext)
|
||||
.has(importedAutoConfiguration(MessageSourceAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validationAutoConfigurationIsImported() {
|
||||
assertThat(this.applicationContext)
|
||||
.has(importedAutoConfiguration(ValidationAutoConfiguration.class));
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link WebFluxTest} and {@link MessageSource} auto-configuration.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebFluxTest
|
||||
@TestPropertySource(properties = "spring.messages.basename=web-test-messages")
|
||||
public class WebFluxTestMessageSourceIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void messageSourceHasBeenAutoConfigured() {
|
||||
assertThat(this.context.getMessage("a", null, Locale.ENGLISH)).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
}
|
@ -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.autoconfigure.web.reactive;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebFluxTest} when a specific controller is defined.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebFluxTest(controllers = ExampleController1.class)
|
||||
public class WebFluxTestOneControllerIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Test
|
||||
public void shouldFindController() {
|
||||
this.webClient
|
||||
.get().uri("/one")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotScanOtherController() {
|
||||
this.webClient
|
||||
.get().uri("/two")
|
||||
.exchange()
|
||||
.expectStatus().isNotFound();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebFluxTypeExcludeFilter}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class WebFluxTypeExcludeFilterTests {
|
||||
|
||||
private MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
|
||||
|
||||
@Test
|
||||
public void matchWhenHasNoControllers() throws Exception {
|
||||
WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
|
||||
WithNoControllers.class);
|
||||
assertThat(excludes(filter, Controller1.class)).isFalse();
|
||||
assertThat(excludes(filter, Controller2.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchWhenHasController() throws Exception {
|
||||
WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
|
||||
WithController.class);
|
||||
assertThat(excludes(filter, Controller1.class)).isFalse();
|
||||
assertThat(excludes(filter, Controller2.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchNotUsingDefaultFilters() throws Exception {
|
||||
WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
|
||||
NotUsingDefaultFilters.class);
|
||||
assertThat(excludes(filter, Controller1.class)).isTrue();
|
||||
assertThat(excludes(filter, Controller2.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleControllerAdvice.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleWeb.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchWithIncludeFilter() throws Exception {
|
||||
WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
|
||||
WithIncludeFilter.class);
|
||||
assertThat(excludes(filter, Controller1.class)).isFalse();
|
||||
assertThat(excludes(filter, Controller2.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchWithExcludeFilter() throws Exception {
|
||||
WebFluxTypeExcludeFilter filter = new WebFluxTypeExcludeFilter(
|
||||
WithExcludeFilter.class);
|
||||
assertThat(excludes(filter, Controller1.class)).isTrue();
|
||||
assertThat(excludes(filter, Controller2.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
|
||||
assertThat(excludes(filter, ExampleService.class)).isTrue();
|
||||
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
|
||||
}
|
||||
|
||||
private boolean excludes(WebFluxTypeExcludeFilter filter, Class<?> type)
|
||||
throws IOException {
|
||||
MetadataReader metadataReader = this.metadataReaderFactory
|
||||
.getMetadataReader(type.getName());
|
||||
return filter.match(metadataReader, this.metadataReaderFactory);
|
||||
}
|
||||
|
||||
@WebFluxTest
|
||||
static class WithNoControllers {
|
||||
|
||||
}
|
||||
|
||||
@WebFluxTest(Controller1.class)
|
||||
static class WithController {
|
||||
|
||||
}
|
||||
|
||||
@WebFluxTest(useDefaultFilters = false)
|
||||
static class NotUsingDefaultFilters {
|
||||
|
||||
}
|
||||
|
||||
@WebFluxTest(includeFilters = @Filter(Repository.class))
|
||||
static class WithIncludeFilter {
|
||||
|
||||
}
|
||||
|
||||
@WebFluxTest(excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Controller1.class))
|
||||
static class WithExcludeFilter {
|
||||
|
||||
}
|
||||
|
||||
@Controller
|
||||
static class Controller1 {
|
||||
|
||||
}
|
||||
|
||||
@Controller
|
||||
static class Controller2 {
|
||||
|
||||
}
|
||||
|
||||
@ControllerAdvice
|
||||
static class ExampleControllerAdvice {
|
||||
|
||||
}
|
||||
|
||||
static class ExampleWeb implements WebFluxConfigurer {
|
||||
|
||||
}
|
||||
|
||||
@Service
|
||||
static class ExampleService {
|
||||
|
||||
}
|
||||
|
||||
@Repository
|
||||
static class ExampleRepository {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.autoconfigure.web.reactive;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringBootTest} with {@link AutoConfigureWebTestClient} (i.e. full
|
||||
* integration test).
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(properties = "spring.main.web-application-type=reactive")
|
||||
@AutoConfigureWebTestClient
|
||||
public class WebTestClientSpringBootTestIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void shouldFindController1() {
|
||||
this.webClient
|
||||
.get().uri("/one")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindController2() {
|
||||
this.webClient
|
||||
.get().uri("/two")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).value().isEqualTo("two");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveRealService() throws Exception {
|
||||
assertThat(this.applicationContext.getBeansOfType(ExampleRealService.class))
|
||||
.hasSize(1);
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
a: alpha
|
@ -0,0 +1 @@
|
||||
a=alpha
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.context;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
/**
|
||||
* Subclass of {@link AnnotationConfigApplicationContext}, suitable for reactive web
|
||||
* environments.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class GenericReactiveWebApplicationContext
|
||||
extends AnnotationConfigApplicationContext
|
||||
implements ReactiveWebApplicationContext {
|
||||
|
||||
public GenericReactiveWebApplicationContext() {
|
||||
super();
|
||||
}
|
||||
|
||||
public GenericReactiveWebApplicationContext(Class<?>[] annotatedClasses) {
|
||||
super(annotatedClasses);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.context;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* Interface to provide configuration for a reactive web application.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface ReactiveWebApplicationContext extends ApplicationContext {
|
||||
|
||||
}
|
Loading…
Reference in New Issue