Skip to content

Commit 1e7c0ec

Browse files
authored
Merge pull request #178 from zonkyio/bean-definition-instance-supplier
#11 Use instance supplier to define data source bean instead of the previous bean factory
2 parents 0c77d0f + 33fa9b4 commit 1e7c0ec

File tree

6 files changed

+112
-9
lines changed

6 files changed

+112
-9
lines changed

embedded-database-spring-test/src/main/java/io/zonky/test/db/EmbeddedDatabaseContextCustomizerFactory.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration;
2222
import io.zonky.test.db.config.EmbeddedDatabaseCondition;
2323
import io.zonky.test.db.context.DatabaseContext;
24+
import io.zonky.test.db.context.DatabaseTargetSource;
2425
import io.zonky.test.db.context.DefaultDatabaseContext;
2526
import io.zonky.test.db.context.EmbeddedDatabaseFactoryBean;
2627
import io.zonky.test.db.provider.DatabaseProvider;
@@ -32,10 +33,12 @@
3233
import io.zonky.test.db.util.PropertyUtils;
3334
import org.slf4j.Logger;
3435
import org.slf4j.LoggerFactory;
36+
import org.springframework.aop.framework.ProxyFactory;
3537
import org.springframework.beans.factory.ObjectFactory;
3638
import org.springframework.beans.factory.config.BeanDefinition;
3739
import org.springframework.beans.factory.config.BeanDefinitionHolder;
3840
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
41+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
3942
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
4043
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
4144
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -68,6 +71,7 @@
6871
import java.util.LinkedHashSet;
6972
import java.util.List;
7073
import java.util.Set;
74+
import java.util.function.Supplier;
7175

7276
import static java.util.stream.Collectors.toCollection;
7377

@@ -302,11 +306,20 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
302306
});
303307

304308
RootBeanDefinition dataSourceDefinition = new RootBeanDefinition();
305-
dataSourceDefinition.setBeanClass(EmbeddedDatabaseFactoryBean.class);
306-
dataSourceDefinition.setPrimary(dataSourceInfo.getBeanDefinition().isPrimary());
307-
dataSourceDefinition.getConstructorArgumentValues()
308-
.addIndexedArgumentValue(0, (ObjectFactory<DatabaseContext>) () ->
309-
beanFactory.getBean(contextBeanName, DatabaseContext.class));
309+
if (ClassUtils.hasMethod(AbstractBeanDefinition.class, "setInstanceSupplier", Supplier.class)) {
310+
dataSourceDefinition.setBeanClass(DataSource.class);
311+
dataSourceDefinition.setPrimary(dataSourceInfo.getBeanDefinition().isPrimary());
312+
dataSourceDefinition.setInstanceSupplier(() -> {
313+
DatabaseContext databaseContext = beanFactory.getBean(contextBeanName, DatabaseContext.class);
314+
return ProxyFactory.getProxy(DataSource.class, new DatabaseTargetSource(databaseContext));
315+
});
316+
} else {
317+
dataSourceDefinition.setBeanClass(EmbeddedDatabaseFactoryBean.class);
318+
dataSourceDefinition.setPrimary(dataSourceInfo.getBeanDefinition().isPrimary());
319+
dataSourceDefinition.getConstructorArgumentValues()
320+
.addIndexedArgumentValue(0, (ObjectFactory<DatabaseContext>) () ->
321+
beanFactory.getBean(contextBeanName, DatabaseContext.class));
322+
}
310323

311324
logger.info("Replacing '{}' DataSource bean with embedded version", dataSourceBeanName);
312325

embedded-database-spring-test/src/main/java/io/zonky/test/db/context/EmbeddedDatabaseFactoryBean.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
* Implementation of the {@link org.springframework.beans.factory.FactoryBean} interface
2828
* that provides fully cacheable instances of the embedded postgres database.
2929
*/
30-
// TODO: replace by using factory method (java configuration)
3130
public class EmbeddedDatabaseFactoryBean implements FactoryBean<DataSource>, Ordered {
3231

3332
private final ObjectFactory<DatabaseContext> databaseContextProvider;

embedded-database-spring-test/src/test/java/io/zonky/test/db/FlywayTransactionalIntegrationTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.zonky.test.category.FlywayTestSuite;
2121
import io.zonky.test.db.context.DatabaseContext;
2222
import io.zonky.test.db.flyway.FlywayWrapper;
23+
import io.zonky.test.db.flyway.OptimizedFlywayTestExecutionListener;
2324
import io.zonky.test.db.flyway.preparer.MigrateFlywayDatabasePreparer;
2425
import io.zonky.test.support.ConditionalTestRule;
2526
import io.zonky.test.support.SpyPostProcessor;
@@ -38,10 +39,13 @@
3839
import org.springframework.context.annotation.Bean;
3940
import org.springframework.context.annotation.Configuration;
4041
import org.springframework.jdbc.core.JdbcTemplate;
42+
import org.springframework.test.context.TestExecutionListeners;
4143
import org.springframework.test.context.TestPropertySource;
4244
import org.springframework.test.context.junit4.SpringRunner;
45+
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
4346
import org.springframework.test.context.transaction.AfterTransaction;
4447
import org.springframework.test.context.transaction.BeforeTransaction;
48+
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
4549

4650
import javax.sql.DataSource;
4751

@@ -61,6 +65,11 @@
6165
"spring.liquibase.enabled=false"
6266
})
6367
@JdbcTest
68+
@TestExecutionListeners(listeners = {
69+
DependencyInjectionTestExecutionListener.class,
70+
OptimizedFlywayTestExecutionListener.class,
71+
TransactionalTestExecutionListener.class
72+
})
6473
public class FlywayTransactionalIntegrationTest {
6574

6675
@ClassRule
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2020 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 io.zonky.test.db;
18+
19+
import io.zonky.test.category.SpringTestSuite;
20+
import io.zonky.test.support.ConditionalTestRule;
21+
import io.zonky.test.support.TestAssumptions;
22+
import org.junit.ClassRule;
23+
import org.junit.Test;
24+
import org.junit.experimental.categories.Category;
25+
import org.junit.runner.RunWith;
26+
import org.mockito.Mockito;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.context.annotation.Bean;
29+
import org.springframework.context.annotation.Configuration;
30+
import org.springframework.jdbc.core.JdbcTemplate;
31+
import org.springframework.test.context.junit4.SpringRunner;
32+
33+
import javax.sql.DataSource;
34+
35+
import static io.zonky.test.db.AutoConfigureEmbeddedDatabase.DatabaseType.POSTGRES;
36+
import static io.zonky.test.support.MockitoAssertions.mock;
37+
import static org.assertj.core.api.Assertions.assertThat;
38+
39+
@RunWith(SpringRunner.class)
40+
@Category(SpringTestSuite.class)
41+
@AutoConfigureEmbeddedDatabase(type = POSTGRES)
42+
public class SpringProxiedBeanMethodsIntegrationTest {
43+
44+
@ClassRule
45+
public static ConditionalTestRule conditionalTestRule = new ConditionalTestRule(TestAssumptions::assumeSpringSupportsInstanceSupplier);
46+
47+
@Configuration
48+
static class Config {
49+
50+
@Bean
51+
public DataSource dataSource() {
52+
return Mockito.mock(DataSource.class);
53+
}
54+
55+
@Bean
56+
public JdbcTemplate jdbcTemplate() {
57+
return new JdbcTemplate(dataSource());
58+
}
59+
}
60+
61+
@Autowired
62+
private DataSource dataSource;
63+
64+
@Autowired
65+
private JdbcTemplate jdbcTemplate;
66+
67+
@Test
68+
public void checkInitializedBeans() {
69+
assertThat(dataSource).isNotNull().isNot(mock());
70+
assertThat(jdbcTemplate).isNotNull();
71+
}
72+
}

embedded-database-spring-test/src/test/java/io/zonky/test/support/MockitoAssertions.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public class MockitoAssertions {
2828

2929
private MockitoAssertions() {}
3030

31-
public static <T> Condition<T> mockWithName(String name) {
32-
Condition<T> isMock = new Condition<T>("target object should be a mock") {
31+
public static <T> Condition<T> mock() {
32+
return new Condition<T>("target object should be a mock") {
3333
@Override
3434
public boolean matches(T object) {
3535
try {
@@ -39,6 +39,9 @@ public boolean matches(T object) {
3939
}
4040
}
4141
};
42+
}
43+
44+
public static <T> Condition<T> mockWithName(String name) {
4245
Condition<T> hasName = new Condition<T>("mock should have a specified name") {
4346
@Override
4447
public boolean matches(T object) {
@@ -50,6 +53,6 @@ public boolean matches(T object) {
5053
}
5154
};
5255

53-
return allOf(isMock, hasName);
56+
return allOf(mock(), hasName);
5457
}
5558
}

embedded-database-spring-test/src/test/java/io/zonky/test/support/TestAssumptions.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package io.zonky.test.support;
22

33
import io.zonky.test.db.flyway.FlywayClassUtils;
4+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
45
import org.springframework.util.ClassUtils;
56

7+
import java.util.function.Supplier;
8+
69
import static org.junit.Assume.assumeTrue;
710

811
public class TestAssumptions {
@@ -25,6 +28,10 @@ private static void assumeFlywayVersion(int minVersion) {
2528
assumeTrue(FlywayClassUtils.getFlywayVersion() >= minVersion);
2629
}
2730

31+
public static void assumeSpringSupportsInstanceSupplier() {
32+
assumeTrue(ClassUtils.hasMethod(AbstractBeanDefinition.class, "setInstanceSupplier", Supplier.class));
33+
}
34+
2835
public static void assumeSpringBootSupportsJdbcTestAnnotation() {
2936
assumeTrue(ClassUtils.isPresent("org.springframework.boot.test.autoconfigure.jdbc.JdbcTest", TestAssumptions.class.getClassLoader()));
3037
}

0 commit comments

Comments
 (0)