Spring boot does not allow custom properties from application.properties during integration tests

My Spring test boot file configuration is as follows:

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {TestEnd2EndIntegrationConfiguration.class}) @WebAppConfiguration @ActiveProfiles(Profiles.TEST)//=="test" @Transactional public abstract class AbstractEnd2EndIntegrationTest { } 

Then from application-test.properties I have the following custom properties:

 database.hibernate.dialect=org.hibernate.dialect.H2Dialect database.hibernate.hbm2ddl.auto=create database.hibernate.logSqlInfo=true 

What I use as follows:

 @Value("${database.hibernate.dialect}") private String hibernateDialect; 

However, custom properties are not allowed, and I get exceptions, such as:

 com.bignibou.it.controller.signup.SignupRestControllerTest > shouldRejectUnavailableEmailAddress FAILED java.lang.IllegalStateException Caused by: org.springframework.beans.factory.BeanCreationException Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException 

change

Here is my gradle configuration:

  sourceSets { main { output.resourcesDir = output.classesDir } integrationTest { java.srcDirs = ['src/it/java'] resources.srcDirs = ['src/it/resources', 'src/main/resources'] compileClasspath = sourceSets.main.output + configurations.testRuntime runtimeClasspath = output + compileClasspath } } task integrationTest(type: Test) { description "Run the integration tests." testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath reports.html.destination = file("$reports.html.destination/integration") reports.junitXml.destination = file("$reports.junitXml.destination/integration") } 

change 2 :

When I run tests from the IDE (intellij), I get another error:

 ava:342) at org.springframework.boot.SpringApplication.run(SpringApplication.java:273) at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ... 36 more java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:183) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:123) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:217) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:276) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:278) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) Caused by: java.lang.ClassCastException: org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources cannot be cast to org.springframework.boot.context.config.ConfigFileEnvironmentPostProcessor$ConfigurationPropertySources at org.springframework.boot.context.config.ConfigFileEnvironmentPostProcessor$ConfigurationPropertySources.finishAndRelocate(ConfigFileEnvironmentPostProcessor.java:528) at org.springframework.boot.context.config.ConfigFileEnvironmentPostProcessor$PropertySourceOrderingPostProcessor.reorderSources(ConfigFileEnvironmentPostProcessor.java:239) at org.springframework.boot.context.config.ConfigFileEnvironmentPostProcessor$PropertySourceOrderingPostProcessor.postProcessBeanFactory(ConfigFileEnvironmentPostProcessor.java:235) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:284) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:131) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:673) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:519) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:667) at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:342) at org.springframework.boot.SpringApplication.run(SpringApplication.java:273) at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ... 36 more 

change 3 :

Here is the detailed reason from gradle integrationTest

 Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [${database.hibernate.ejb.naming_strategy}] as strategy [org.hibernate.cfg.NamingStrategy] at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.selectStrategyImplementor(StrategySelectorImpl.java:128) at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.resolveDefaultableStrategy(StrategySelectorImpl.java:155) at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.resolveStrategy(StrategySelectorImpl.java:136) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.processProperties(EntityManagerFactoryBuilderImpl.java:925) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:840) at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 

change 4 : from debugging inside: EntityManagerFactoryBuilderImpl :

 configurationValues = { HashMap@4101 } size = 14 0 = { HashMap$Node@4092 } "hibernate.format_sql" -> "${database.hibernate.logSqlInfo}" 1 = { HashMap$Node@4096 } "hibernate.use_sql_comments" -> "${database.hibernate.logSqlInfo}" 2 = { HashMap$Node@4107 } "javax.persistence.nonJtaDataSource" -> 3 = { HashMap$Node@4108 } "hibernate.hbm2ddl.auto" -> "${database.hibernate.hbm2ddl.auto}" 4 = { HashMap$Node@4109 } "javax.persistence.sharedCache.mode" -> "ENABLE_SELECTIVE" 5 = { HashMap$Node@4110 } "hibernate.dialect" -> "${database.hibernate.dialect}" 6 = { HashMap$Node@4111 } "hibernate.ejb.naming_strategy" -> "${database.hibernate.ejb.naming_strategy}" 7 = { HashMap$Node@4112 } "hibernate.cache.use_second_level_cache" -> "${database.hibernate.cache.use_second_level_cache}" 8 = { HashMap$Node@4113 } "hibernate.ejb.persistenceUnitName" -> "default" 9 = { HashMap$Node@4114 } "hibernate.connection.charSet" -> "${database.hibernate.connection.charSet}" 10 = { HashMap$Node@4115 } "hibernate.show_sql" -> "${database.hibernate.logSqlInfo}" 11 = { HashMap$Node@4116 } "hibernate.cache.region.factory_class" -> "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" 12 = { HashMap$Node@4117 } "hibernate.generate_statistics" -> "${database.hibernate.generate_statistics}" 13 = { HashMap$Node@4118 } "javax.persistence.validation.mode" -> "AUTO" 

It can be seen that the properties are not expanded ... Why is this?

+6
source share
3 answers

In fact, the problem was the following line of code:

 @SpringApplicationConfiguration(classes = {TestEnd2EndIntegrationConfiguration.class}) 

TestEnd2EndIntegrationConfiguration not a Spring boot application with the main one and, most importantly, it is not annotated with the @EnableAutoConfiguration annotation.

I changed to:

 @Configuration @EnableAutoConfiguration(exclude = { ManagementWebSecurityAutoConfiguration.class, ... MailSenderAutoConfiguration.class }) @ComponentScan(basePackages = {"com.bignibou.configuration", "com.bignibou.it.configuration"}) public class TestApplication { public static void main(String[] args) throws Exception { SpringApplication.run(TestApplication.class, args); } } 

and my abstract test class:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {TestApplication.class})//Notice the change @WebAppConfiguration @ActiveProfiles(Profiles.TEST) @Transactional public abstract class AbstractIntegrationTest { } 

Tests now run as a Spring boot application, and custom properties in application.properties also allowed.

+8
source

You need 3 things so that your properties are automatically added to your integration test classes:

  • PropertySource Annotations. It seems like you are missing it. You can add something like this to your abstract integration test class:
 @PropertySource(value= {"classpath:*.properties"}) 
  1. The properties file should be in your classpath. I recommend adding a separate folder for test and test test properties. Create the integration-test-resources directory in src/main and copy your properties files there, and then configure the build manager to add them as class resources.

Here is an example of how to do this in Gradle:

 sourceSets { integrationTest { resources { srcDir "integration-test-resources" } } } 
  1. Annotate your property with @Value . It looks like you are already doing this.
+9
source

I believe that you should use spring.jpa.hibernate.dll-auto if you want to put your Hibernate properties in the application-${profile}.properties properties file application-${profile}.properties , i.e. Spring

In addition, you should use spring.jpa.database-platform=org.hibernate.dialect.H2Dialect .

I use Spring Boot with this configuration, and I never needed any @PropertySource annotations.

+3
source

All Articles