Интеграционный тест Spring: несовместимые компоненты с одинаковым именем и классом

Я работаю над решением странной проблемы с моим проектом, которая возникла с тех пор, как мы начали работать над интеграционным тестированием. Что происходит, так это то, что я использую «jetty-maven-plugin» для запуска экземпляра приложения, после его запуска «maven-failsafe-plugin» начинает запускать интеграционные тесты. Это очень хорошо настроено и работает.

Сейчас я пытаюсь сделать следующее: я хотел бы получить доступ к моему сервисному уровню, чтобы я мог настроить некоторые приборы для запуска моих тестов. До сих пор наши интеграционные тесты были довольно простыми, и я хотел бы поднять их на ступеньку выше и протестировать фактическое заполнение форм и так далее. Чтобы это работало, мне нужно настроить некоторые приборы, а затем удалить их, чтобы эти тесты воспроизводились. Мы работаем с тестовой базой данных, которую используем именно для этой цели.

Судя по тому, что я читал, это неразумно. Тем не менее, когда я действительно запускаю тесты, я получаю очень странное сообщение об ошибке и трассировку стека. Насколько я могу судить, Maven без проблем запускает приложение в Jetty. Затем отказоустойчивый подключаемый модуль запускает тест и, как только он достигает первого интеграционного теста, начинает создавать экземпляр Spring и контекст. Он правильно извлекает свои свойства и файлы конфигурации, но когда он пытается фактически внедрить объект службы, я вижу эту ошибку:

Вызвано: org.springframework.beans.factory.BeanDefinitionStoreException: непредвиденное исключение при синтаксическом анализе XML-документа из ресурса пути к классу [app-config.xml]; вложенным исключением является org.springframework.context.annotation.Conflicting BeanDefinitionException: указанное в аннотации имя компонента «pesticideRoleRepositoryImpl» для класса компонента [dao.role.PesticideRoleRepositoryImpl] конфликтует с существующим несовместимым определением компонента с тем же именем и классом [dao.role .PesticideRoleRepositoryImpl]

Я избавлю вас от всей трассировки стека, я могу сделать ее доступной в любое время. ;-)

Я начал задаваться вопросом, не ошибусь ли я во всем этом, и поэтому я вернулся и настроил тестовый проект почти таким же образом. Тестовый проект намного проще и не имеет этой проблемы. Когда он запускает интеграционные тесты, объекты службы внедряются без проблем. Если вам интересно, вы можете взглянуть на мой тестовый проект на GitHub.

Мой вопрос заключается в следующем...

Кто-нибудь видел эту ошибку раньше? Могут ли быть какие-то условия, при которых у Spring возникнет такая проблема?

Мне ясно, что при таком интеграционном тестировании я получаю два контейнера Spring, которые используют одну и ту же конфигурацию. Я думал, что это может быть проблемой, но тестовый проект работает так же и не имеет этой проблемы. Меня также беспокоит тот факт, что даже при наличии двух компонентов с одинаковым именем и классом Spring считает, что они несовместимы.

Спасибо, любая помощь будет принята с благодарностью! :-D


person Miles    schedule 23.03.2013    source источник
comment
Можете ли вы проверить, что такое ClassLoaders для двух классов?   -  person Eric Jablow    schedule 23.03.2013
comment
Я не уверен, как получить эту информацию, ошибка выдается до запуска моего теста. Я вижу, что org.apache.maven.surefire.booter.ForkedBooter.main выполняет тест. Я попытаюсь создать экземпляр контейнера вручную и посмотреть, смогу ли я вручную загрузить компонент репозитория (в нем нет введенных полей).   -  person Miles    schedule 23.03.2013


Ответы (2)


Эта ошибка возникает, когда два разных файла содержат одно и то же определение класса (компонента) и несовместимы, т.е. oldBeanDefintion.equals(newBeanDefinition) == false

Вы можете проверить:

  • Почему сканер загружает этот класс дважды.
  • Почему oldBeanDefintion.getSource().equals(newBeanDefinition.getSource()) = false
  • Почему oldBeanDefinition.equals(newBeanDefinition) = false

Вы можете поставить точку останова на ClassPathBeanDefinitionScanner.isCompatible() или расширить ClassPathBeanDefinitionScanner и переопределить метод isCompatible и записать некоторую полезную информацию, чтобы найти ошибку.

Как последний вариант, XML BeanDefinitions не может быть переопределен отсканированными, поэтому, если вы определяете bean-компонент в XML, отсканированные классы с тем же именем bean-компонента будут игнорироваться.

person Jose Luis Martin    schedule 23.03.2013

Выбранный ответ был правильным, основная проблема заключалась в том, что было создано несколько экземпляров bean-компонента. Интересно, однако, что другие экземпляры были фиктивными экземплярами; их подбирали, потому что они были смешаны с тестами, и все тесты были помещены в путь к классам.

Вероятно, есть много решений, мое исправление состояло в том, чтобы добавить «контекст: фильтр исключения» к объявлению «контекст: компонент-сканирование» в моей конфигурации приложения.

person Miles    schedule 01.04.2013