Подтвердить что ты не робот

Весенние профили и тестирование

У меня есть веб-приложение, где у меня есть типичная проблема, которая требует разных файлов конфигурации для разных сред. Некоторая конфигурация размещается на сервере приложений как источники данных 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, которая фактически вызывает нормальный контекст?

4b9b3361

Ответ 1

Могу ли я рекомендовать это сделать так, определите свой тест следующим образом:

@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

При этом ваш второй файл свойств должен быть разрешен:

META-INF/spring/config_${spring.profiles.active}.properties

Ответ 2

Глядя на ответ Биджу, я нашел рабочее решение.

Я создал дополнительный файл-контекст 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(){

  }
}

Это экономит некоторую работу при создании нескольких тестовых случаев.

Ответ 3

Наилучшим подходом здесь является удаление аннотации @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"/>

Ответ 4

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" };
    }
}

Это устанавливает профиль, который затем используется для разрешения зависимостей, требуемых тестом.