さまざまな環境に応じてさまざまな構成ファイルを必要とするという典型的な問題があるWebアプリケーションがあります。一部の構成はJNDIデータソースとしてアプリケーションサーバーに配置されますが、一部の構成はプロパティファイルに残ります。
したがって、Springプロファイル機能を使用したいと思います。
私の問題は、テストケースが実行されないことです。
context.xml:
<context:property-placeholder
location="classpath:META-INF/spring/config_${spring.profiles.active}.properties"/>
テスト:
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
TestPreperationExecutionListener.class
})
@Transactional
@ActiveProfiles(profiles = "localtest")
@ContextConfiguration(locations = {
"classpath:context.xml" })
public class TestContext {
@Test
public void testContext(){
}
}
問題は、プロファイルをロードするための変数が解決されていないことです。
Caused by: Java.io.FileNotFoundException: class path resource [META-INF/spring/config_${spring.profiles.active}.properties] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.Java:157)
at org.springframework.core.io.support.PropertiesLoaderSupport.loadProperties(PropertiesLoaderSupport.Java:181)
at org.springframework.core.io.support.PropertiesLoaderSupport.mergeProperties(PropertiesLoaderSupport.Java:161)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(PropertySourcesPlaceholderConfigurer.Java:138)
... 31 more
現在のプロファイルは、@ActiveProfile
アノテーションで設定する必要があります。テストケースなので、web.xml
を使用することはできません。可能であれば、ランタイムオプションも回避したいと思います。テストはそのまま実行する必要があります(可能な場合)。
プロファイルを適切に有効化するにはどうすればよいですか? context.xmlを使用してプロファイルを設定することは可能ですか?実際に通常のコンテキストを呼び出しているtest-context.xmlで変数を宣言できますか?
この方法でこれを行うことをお勧めします。テストを次のように定義します。
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
TestPreperationExecutionListener.class
})
@Transactional
@ActiveProfiles(profiles = "localtest")
@ContextConfiguration
public class TestContext {
@Test
public void testContext(){
}
@Configuration
@PropertySource("classpath:/myprops.properties")
@ImportResource({"classpath:context.xml" })
public static class MyContextConfiguration{
}
}
myprops.propertiesファイルに次のコンテンツが含まれます。
spring.profiles.active=localtest
これにより、2番目のプロパティファイルが解決されます。
META-INF/spring/config_${spring.profiles.active}.properties
Bijuの答えを見て、実用的な解決策を見つけました。
追加のコンテキストファイルtest-context.xml
を作成しました。
<context:property-placeholder location="classpath:config/spring-test.properties"/>
プロファイルを含む:
spring.profiles.active=localtest
そして、テストをロードする:
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
TestPreperationExecutionListener.class
})
@Transactional
@ActiveProfiles(profiles = "localtest")
@ContextConfiguration(locations = {
"classpath:config/test-context.xml" })
public class TestContext {
@Test
public void testContext(){
}
}
これにより、複数のテストケースを作成する際の作業が節約されます。
ここでの最善のアプローチは、@ ActiveProfilesアノテーションを削除して、次のことを行うことです。
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
TestPreperationExecutionListener.class
})
@Transactional
@ContextConfiguration(locations = {
"classpath:config/test-context.xml" })
public class TestContext {
@BeforeClass
public static void setSystemProperty() {
Properties properties = System.getProperties();
properties.setProperty("spring.profiles.active", "localtest");
}
@AfterClass
public static void unsetSystemProperty() {
System.clearProperty("spring.profiles.active");
}
@Test
public void testContext(){
}
}
また、test-context.xmlには次のものが必要です。
<context:property-placeholder
location="classpath:META-INF/spring/config_${spring.profiles.active}.properties"/>
public class LoginTest extends BaseTest {
@Test
public void exampleTest( ){
// Test
}
}
基本テストクラスから継承します(この例はtestng
ではなくjUnit
ですが、ActiveProfiles
は同じです):
@ContextConfiguration(locations = { "classpath:spring-test-config.xml" })
@ActiveProfiles(resolver = MyActiveProfileResolver.class)
public class BaseTest extends AbstractTestNGSpringContextTests { }
MyActiveProfileResolver
には、使用するプロファイルを決定するために必要なロジックを含めることができます。
public class MyActiveProfileResolver implements ActiveProfilesResolver {
@Override
public String[] resolve(Class<?> aClass) {
// This can contain any custom logic to determine which profiles to use
return new String[] { "exampleProfile" };
}
}
これにより、テストに必要な依存関係を解決するために使用されるプロファイルが設定されます。