Проблемы пользовательского загрузчика 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)

Другие вопросы по тегам