Add "testing your auto-configuration" doc section
Closes gh-10011
This commit is contained in:
parent
175f451b0f
commit
e274f29018
|
@ -53,6 +53,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson;
|
||||||
:propdeps-plugin: https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin
|
:propdeps-plugin: https://github.com/spring-projects/gradle-plugins/tree/master/propdeps-plugin
|
||||||
:ant-manual: http://ant.apache.org/manual
|
:ant-manual: http://ant.apache.org/manual
|
||||||
:code-examples: ../java/org/springframework/boot
|
:code-examples: ../java/org/springframework/boot
|
||||||
|
:test-examples: ../../test/java/org/springframework/boot
|
||||||
:gradle-user-guide: https://docs.gradle.org/4.2.1/userguide
|
:gradle-user-guide: https://docs.gradle.org/4.2.1/userguide
|
||||||
:hibernate-documentation: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html
|
:hibernate-documentation: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html
|
||||||
:jetty-documentation: https://www.eclipse.org/jetty/documentation/9.4.x
|
:jetty-documentation: https://www.eclipse.org/jetty/documentation/9.4.x
|
||||||
|
|
|
@ -7101,6 +7101,66 @@ result of a {spring-reference}core.html#expressions[SpEL expression].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[boot-features-test-autoconfig]]
|
||||||
|
=== Testing your auto-configuration
|
||||||
|
An auto-configuration can be affected by many factors: user configuration (`@Bean`
|
||||||
|
definition and `Environment` customization), condition evaluation (presence of a
|
||||||
|
particular library), etc. Concretely, each test should create a well-defined
|
||||||
|
`ApplicationContext` that represents a combination of those customizations and
|
||||||
|
`ApplicationContextRunner` provides a great way to achieve that.
|
||||||
|
|
||||||
|
`ApplicationContextRunner` is usually defined as a field of the test class to gather the
|
||||||
|
base, common configuration. The following makes sure that `UserServiceAutoConfiguration`
|
||||||
|
is always invoked:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=runner]
|
||||||
|
----
|
||||||
|
|
||||||
|
TIP: If multiple auto-configurations have to be defined, there is no need to order their
|
||||||
|
declarations as they will be invoked in the exact same order as when running the
|
||||||
|
application.
|
||||||
|
|
||||||
|
Each test can use the runner to represents a particular use case. For instance, the sample
|
||||||
|
below invokes a user configuration (`UserConfiguration`) and checks that the
|
||||||
|
auto-configuration backs off properly. Invoking `run` provides a callback context that can
|
||||||
|
be used with `Assert4J`:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-user-config]
|
||||||
|
----
|
||||||
|
|
||||||
|
It is also possible to easily customize the `Environment`:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-env]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==== Simulating a web context
|
||||||
|
If you need to test an auto-configuration that only operates in a Servlet or Reactive web
|
||||||
|
application context, use the `WebApplicationContextRunner` or
|
||||||
|
`ReactiveWebApplicationContextRunner` respectively.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==== Overriding the classpath
|
||||||
|
It is also possible to test what happens when a particular class and/or package is not
|
||||||
|
present at runtime. Spring Boot ships with a `FilteredClassLoader` that can easily be used
|
||||||
|
by the runner. In the example below, we assert that if `UserService` is not present, the
|
||||||
|
auto-configuration will be properly disabled:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::{test-examples}/autoconfigure/UserServiceAutoConfigurationTests.java[tag=test-classloader]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[boot-features-custom-starter]]
|
[[boot-features-custom-starter]]
|
||||||
=== Creating Your Own Starter
|
=== Creating Your Own Starter
|
||||||
A full Spring Boot starter for a library may contain the following components:
|
A full Spring Boot starter for a library may contain the following components:
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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.autoconfigure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple service.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
class UserService {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
UserService(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.autoconfigure;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.UserServiceAutoConfiguration.UserProperties;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sample auto-configuration.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(UserService.class)
|
||||||
|
@EnableConfigurationProperties(UserProperties.class)
|
||||||
|
public class UserServiceAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public UserService userService(UserProperties properties) {
|
||||||
|
return new UserService(properties.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ConfigurationProperties("user")
|
||||||
|
static class UserProperties {
|
||||||
|
|
||||||
|
private String name = "test";
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.autoconfigure;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link UserServiceAutoConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
public class UserServiceAutoConfigurationTests {
|
||||||
|
|
||||||
|
// tag::runner[]
|
||||||
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withConfiguration(AutoConfigurations.of(UserServiceAutoConfiguration.class));
|
||||||
|
// end::runner[]
|
||||||
|
|
||||||
|
// tag::test-env[]
|
||||||
|
@Test
|
||||||
|
public void serviceNameCanBeConfigured() {
|
||||||
|
this.contextRunner.withPropertyValues("user.name=test123")
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(UserService.class);
|
||||||
|
assertThat(context.getBean(UserService.class).getName())
|
||||||
|
.isEqualTo("test123");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// end::test-env[]
|
||||||
|
|
||||||
|
// tag::test-classloader[]
|
||||||
|
@Test
|
||||||
|
public void serviceIsIgnoredIfLibraryIsNotPresent() {
|
||||||
|
this.contextRunner.withClassLoader(new FilteredClassLoader(UserService.class))
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).doesNotHaveBean("userService");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// end::test-classloader[]
|
||||||
|
|
||||||
|
|
||||||
|
// tag::test-user-config[]
|
||||||
|
@Test
|
||||||
|
public void defaultServiceBacksOff() {
|
||||||
|
this.contextRunner.withUserConfiguration(UserConfiguration.class)
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(UserService.class);
|
||||||
|
assertThat(context.getBean(UserService.class)).isSameAs(
|
||||||
|
context.getBean(UserConfiguration.class).myUserService());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class UserConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public UserService myUserService() {
|
||||||
|
return new UserService("mine");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// end::test-user-config[]
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue