Skip to content

Commit 959d97c

Browse files
committed
Add support for property spring.test.database.replace
See gh-7229
1 parent 1464425 commit 959d97c

File tree

5 files changed

+238
-3
lines changed

5 files changed

+238
-3
lines changed

spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabase.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
2929
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
3030
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
31+
import org.springframework.boot.test.autoconfigure.properties.SkipPropertyMapping;
3132

3233
/**
3334
* Annotation that can be applied to a test class to configure a test database to use
@@ -48,6 +49,7 @@
4849
* Determines what type of existing DataSource beans can be replaced.
4950
* @return the type of existing DataSource to replace
5051
*/
52+
@PropertyMapping(skip = SkipPropertyMapping.ON_DEFAULT_VALUE)
5153
Replace replace() default Replace.ANY;
5254

5355
/**

spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/jdbc/TestDatabaseAutoConfiguration.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,22 @@
3131
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
3232
import org.springframework.beans.factory.support.RootBeanDefinition;
3333
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
34+
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
35+
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
3436
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
35-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
37+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
3638
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
3739
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
40+
import org.springframework.boot.bind.RelaxedPropertyResolver;
3841
import org.springframework.context.EnvironmentAware;
3942
import org.springframework.context.annotation.Bean;
43+
import org.springframework.context.annotation.ConditionContext;
44+
import org.springframework.context.annotation.Conditional;
4045
import org.springframework.context.annotation.Configuration;
4146
import org.springframework.core.Ordered;
4247
import org.springframework.core.annotation.Order;
4348
import org.springframework.core.env.Environment;
49+
import org.springframework.core.type.AnnotatedTypeMetadata;
4450
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
4551
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
4652
import org.springframework.util.Assert;
@@ -50,32 +56,73 @@
5056
* Auto-configuration for a test database.
5157
*
5258
* @author Phillip Webb
59+
* @author Eddú Meléndez
5360
* @since 1.4.0
5461
* @see AutoConfigureTestDatabase
5562
*/
5663
@Configuration
5764
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
5865
public class TestDatabaseAutoConfiguration {
5966

67+
private static final String SPRING_TEST_DATABASE_PREFIX = "spring.test.database.";
68+
private static final String REPLACE_PROPERTY = "replace";
69+
6070
private final Environment environment;
6171

6272
TestDatabaseAutoConfiguration(Environment environment) {
6373
this.environment = environment;
6474
}
6575

6676
@Bean
67-
@ConditionalOnProperty(prefix = "spring.test.database", name = "replace", havingValue = "AUTO_CONFIGURED")
77+
@Conditional(TestDatabaseReplaceAutoConfiguredCondition.class)
6878
@ConditionalOnMissingBean
6979
public DataSource dataSource() {
7080
return new EmbeddedDataSourceFactory(this.environment).getEmbeddedDatabase();
7181
}
7282

7383
@Bean
74-
@ConditionalOnProperty(prefix = "spring.test.database", name = "replace", havingValue = "ANY", matchIfMissing = true)
84+
@Conditional(TestDatabaseReplaceAnyCondition.class)
7585
public static EmbeddedDataSourceBeanFactoryPostProcessor embeddedDataSourceBeanFactoryPostProcessor() {
7686
return new EmbeddedDataSourceBeanFactoryPostProcessor();
7787
}
7888

89+
static class TestDatabaseReplaceAutoConfiguredCondition extends SpringBootCondition {
90+
91+
@Override
92+
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata
93+
metadata) {
94+
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), SPRING_TEST_DATABASE_PREFIX);
95+
ConditionMessage.Builder message = ConditionMessage
96+
.forCondition("Test Database Replace Property");
97+
if (resolver.containsProperty(REPLACE_PROPERTY) && "NONE".equals(resolver.getProperty(REPLACE_PROPERTY))) {
98+
return ConditionOutcome.noMatch(message.didNotFind("NONE").atAll());
99+
}
100+
else if (resolver.containsProperty(REPLACE_PROPERTY) && "AUTO_CONFIGURED".equals(resolver.getProperty(REPLACE_PROPERTY))) {
101+
return ConditionOutcome.match(message.found("AUTO_CONFIGURED").atAll());
102+
}
103+
return ConditionOutcome.noMatch(message.didNotFind("spring.test.database.replace").atAll());
104+
}
105+
106+
}
107+
108+
static class TestDatabaseReplaceAnyCondition extends SpringBootCondition {
109+
110+
@Override
111+
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
112+
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), SPRING_TEST_DATABASE_PREFIX);
113+
ConditionMessage.Builder message = ConditionMessage
114+
.forCondition("Test Database Replace Property");
115+
if (resolver.containsProperty(REPLACE_PROPERTY) && "NONE".equals(resolver.getProperty(REPLACE_PROPERTY))) {
116+
return ConditionOutcome.noMatch(message.didNotFind("NONE").atAll());
117+
}
118+
else if (!resolver.containsProperty(REPLACE_PROPERTY) || "ANY".equals(resolver.getProperty(REPLACE_PROPERTY))) {
119+
return ConditionOutcome.match(message.found("ANY").atAll());
120+
}
121+
return ConditionOutcome.noMatch(message.didNotFind("spring.test.database.replace").atAll());
122+
}
123+
124+
}
125+
79126
@Order(Ordered.LOWEST_PRECEDENCE)
80127
private static class EmbeddedDataSourceBeanFactoryPostProcessor
81128
implements BeanDefinitionRegistryPostProcessor {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.jdbc;
18+
19+
import javax.sql.DataSource;
20+
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
26+
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
30+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
31+
import org.springframework.test.context.TestPropertySource;
32+
import org.springframework.test.context.junit4.SpringRunner;
33+
34+
import static org.assertj.core.api.Assertions.assertThat;
35+
36+
/**
37+
* Integration tests for {@link JdbcTest}.
38+
*
39+
* @author Phillip Webb
40+
* @author Stephane Nicoll
41+
*/
42+
@RunWith(SpringRunner.class)
43+
@JdbcTest
44+
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQL)
45+
@TestPropertySource(properties = "spring.test.database.replace=ANY")
46+
public class JdbcTestWithAutoConfigureTestDatabaseReplacePropertyAnyIntegrationTests {
47+
48+
@Autowired
49+
private DataSource dataSource;
50+
51+
@Test
52+
public void replacesDefinedDataSourceWithExplicit() throws Exception {
53+
// H2 is explicitly defined but HSQL is the override.
54+
String product = this.dataSource.getConnection().getMetaData()
55+
.getDatabaseProductName();
56+
assertThat(product).startsWith("HSQL");
57+
}
58+
59+
@Configuration
60+
@EnableAutoConfiguration
61+
static class Config {
62+
63+
@Bean
64+
public DataSource dataSource() {
65+
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
66+
.generateUniqueName(true)
67+
.setType(EmbeddedDatabaseType.H2);
68+
return builder.build();
69+
}
70+
71+
}
72+
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.jdbc;
18+
19+
import javax.sql.DataSource;
20+
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
26+
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.test.context.TestPropertySource;
29+
import org.springframework.test.context.junit4.SpringRunner;
30+
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
33+
/**
34+
* Integration tests for {@link JdbcTest}.
35+
*
36+
* @author Phillip Webb
37+
* @author Stephane Nicoll
38+
*/
39+
@RunWith(SpringRunner.class)
40+
@JdbcTest
41+
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQL)
42+
@TestPropertySource(properties = "spring.test.database.replace=AUTO_CONFIGURED")
43+
public class JdbcTestWithAutoConfigureTestDatabaseReplacePropertyAutoConfiguredIntegrationTests {
44+
45+
@Autowired
46+
private DataSource dataSource;
47+
48+
@Test
49+
public void replacesAutoConfiguredDataSource() throws Exception {
50+
String product = this.dataSource.getConnection().getMetaData()
51+
.getDatabaseProductName();
52+
assertThat(product).startsWith("HSQL");
53+
}
54+
55+
@Configuration
56+
@EnableAutoConfiguration // Will auto-configure H2
57+
static class Config {
58+
59+
}
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.jdbc;
18+
19+
import javax.sql.DataSource;
20+
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.test.context.TestPropertySource;
26+
import org.springframework.test.context.junit4.SpringRunner;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
30+
/**
31+
* Integration tests for {@link JdbcTest}.
32+
*
33+
* @author Phillip Webb
34+
* @author Stephane Nicoll
35+
*/
36+
@RunWith(SpringRunner.class)
37+
@JdbcTest
38+
@TestPropertySource(properties = "spring.test.database.replace=NONE")
39+
public class JdbcTestWithAutoConfigureTestDatabaseReplacePropertyNoneIntegrationTests {
40+
41+
@Autowired
42+
private DataSource dataSource;
43+
44+
@Test
45+
public void usesDefaultEmbeddedDatabase() throws Exception {
46+
// HSQL is explicitly defined and should not be replaced
47+
String product = this.dataSource.getConnection().getMetaData()
48+
.getDatabaseProductName();
49+
assertThat(product).startsWith("HSQL");
50+
}
51+
52+
}

0 commit comments

Comments
 (0)