Проблемы пользовательского загрузчика ContextConfiguration при обновлении с Spring Framework 4.2.9 до 4.3+
У меня возникают некоторые проблемы с выполнением моих интеграционных тестов после обновления зависимости Spring-Spring Spring 4.2.9 до 4.3.9.
Я использую класс ContextConfiguration, который реализует весенний тест SmartContextLoader
что позволило мне загрузить различные XML-файлы конфигурации, которые разделены по профилям. Основываясь на текущем весеннем профиле, он будет запускать конкретные бины для этого профиля.
это ContextConfigurationLoader
Я отлично работал в версии 4.2.9
но после обновления до версии 4.3
и я изо всех сил пытаюсь решить эту проблему.
Я в том числе ContextConfigurationLoader
Я создал в своих интеграционных тестах так.
@ContextConfiguration(loader=ContextConfigurationLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class MyIntegrationTest {
// Test Body
}
ContextConfigurationLoader
выглядит так,
public class ContextConfigurationLoader implements SmartContextLoader {
@Override
public void processContextConfiguration(ContextConfigurationAttributes contextConfigurationAttributes) {
}
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedContextConfiguration) throws Exception {
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.getEnvironment().setActiveProfiles(mergedContextConfiguration.getActiveProfiles());
new XmlBeanDefinitionReader(context).
loadBeanDefinitions(mergedContextConfiguration.getLocations());
context.load(
"/development.xml",
"/staging.xml",
"/production.xml",
);
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
context.refresh();
context.registerShutdownHook();
return context;
}
@Override
public String[] processLocations(Class<?> aClass, String... strings) {
return new String[0];
}
@Override
public ApplicationContext loadContext(String... strings) throws Exception {
ApplicationContext context = ApplicationContextFactory.create();
context.getBean("dbUnitDatabaseConnection");
return ApplicationContextFactory.create();
}
}
Наконец, это ответ об ошибке, которую я получаю после попытки запустить мои тесты.
java.lang.IllegalStateException: ContextConfigurationLoader was unable to detect defaults, and no ApplicationContextInitializers or ContextCustomizers were declared for context configuration attributes [[ContextConfigurationAttributes@53ca01a2 declaringClass = 'com.class.path.to.MyIntegrationTest', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'com.class.path.to.ContextConfigurationLoader']]
Спасибо за вашу помощь, дайте мне знать, если вам нужна дополнительная информация.
Одно решение, которое я нашел, - это объединение всех XML-файлов конфигурации в один файл и использование @ContextConfiguration
аннотация, как это.
@ContextConfiguration("/config.xml")
Но это потребует некоторых других изменений в остальной части кода вне тестов. Это также не помогает объяснить, почему моя текущая реализация не работает с последней версией Spring Framework для весеннего тестирования.
1 ответ
От Javadoc SmartContextLoader.processContextConfiguration(ContextConfigurationAttributes)
:
Примечание: в отличие от стандартного ContextLoader, SmartContextLoader должен предварительно проверить, что сгенерированное или обнаруженное значение по умолчанию действительно существует, прежде чем устанавливать соответствующие свойства местоположений или классов в предоставленных ContextConfigurationAttributes. Следовательно, оставляя пустым свойство местоположений или классов, сигнализирует о том, что этот SmartContextLoader не смог сгенерировать или обнаружить значения по умолчанию.
Поведение, описанное в последнем предложении, вызывает у вас проблемы.
Таким образом, решение вашей проблемы было бы на самом деле реализовать processContextConfiguration()
и установите фиктивное местоположение в поставляемом ContextConfigurationAttributes
, Это указало бы Spring на то, что ваш пользовательский загрузчик смог правильно определить значения по умолчанию (которые вы жестко кодируете в loadContext()
). Затем вы можете удалить фиктивное местоположение из копии mergedContextConfiguration.getLocations()
прежде чем передать их loadBeanDefinitions()
,
Это сделало бы его более чистым для конечных пользователей; однако альтернативой (если у вас нет конечных пользователей, кроме вас самих) было бы объявить местоположение существующего XML-файла конфигурации (через @ContextConfiguration
Это просто не объявляет никаких бобов.
С Уважением,
Сэм (автор Spring TestContext Framework)