Весенние контекстные тесты не могут найти расположения конфигураций


У меня есть большое приложение, разбросанное по нескольким xml-файлам Spring bean definition. В моем тестовом наборе я вручную загружаю XML-файлы, которые мне нужны, используя FileSystemXmlApplicationContext для выполнения тестов, которые я хочу запустить. Это сокращает время настройки теста и позволяет мне использовать те же самые файлы конфигурации, которые используются в производстве.

Теперь я пытаюсь использовать базовые классы транзакционного теста Spring, которые принимают расположение конфигурации и загружают контекст для меня. По какой-то причине, когда контекст приложения создается весной не удается найти ни один из файлов конфигурации. Это сбивает с толку, потому что я запускаю тест из того же рабочего каталога, что и при загрузке конфигурации с помощью FileSystemXmlApplicationContext. Если я добавляю перед всеми моими конфигурационными местоположениями "file:" пути, которые я указываю в своем тесте, найдены, но любые файлы, которые импортируются или на которые ссылаются бобы, определенные в конфигурации (например, файлы свойств), не могут быть найдены. В чем же дело? Могу ли я получить тесты, которые продлят весну контекстные тестовые классы работают так же, как и те, где я сам создаю контекст?

Например, создание такого контекста прекрасно работает:

ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[] { "WEB-INF/services-context.xml"})

Если я расширяю AbstractTransactionalDataSourceSpringcontexttests, то следующее не находит services-context.xml:

@Override
protected String[] getConfigLocations() {
   return new String[] { "WEB-INF/services-context.xml"};
}

Это находит services-context, но PropertyPlaceholderConfigurer, определенный в нем, не может найти файлы свойств.

 @Override
 protected String[] getConfigLocations() {
    return new String[] { "file:WEB-INF/services-context.xml"};
 }
6 8

6 ответов:

Мы помещаем все наши файлы конфигурации и свойств Spring в путь к классу, что упрощает задачу-мы можем просто расширить наши тестовые классы из базового класса, например:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
        "/spring/*.xml", 
        "/testSpring/*.xml" })
public abstract class AbstractIntegrationTest  {

Здесь пути-это все пути в classpath.

Если вы не хотите этого делать, проверьте, как вы ссылаетесь на файлы свойств в контексте служб.в XML? Я подозреваю,что если вы добавляете file: в свою контекстную конфигурацию, то вам также нужно будет добавить это в ссылку на файл свойств. Вы возможно, вы можете просто использовать отдельный конфигурационный файл test Spring для изменения определения заполнителя вашего свойства и поместить его в конец списка контекстных файлов - его определения затем переопределят те, которые были определены в предыдущих файлах.

В дополнение к переопределению getConfigLocations я также переопределил loadContext и использовал надежный fileSystemXmlApplicationContext там.

 @Override
 protected String[] getConfigLocations() {
     return new String[] { "WEB-INF/services-config.xml" };
 }

 @Override
 protected ConfigurableApplicationContext loadContext(String[] locations) throws Exception {
     return new FileSystemXmlApplicationContext(locations);
  }

Ваши конфигурационные местоположения являются относительными URI и будут интерпретироваться как таковые базовым тестовым классом, причем URI будет разрешен относительно местоположения самого тестового класса. Попробуйте использовать полные URI или относительные URI, принимая во внимание, где находится тестовый класс.

Нельзя ли использовать XML-фабрики classpath, такие как ClassPathXmlApplicationContext?

Другим возможным решением является дублирование services-config.xml и переименование в services-config-test.xml, а затем поместить под classpath. То же самое относится и к файлу свойств.

ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[] { "WebRoot/WEB-INF/services-context.xml"})