Spring Test Framework и аннотации на основе проблемы с автопроводкой - PullRequest
5 голосов
/ 08 июля 2010

Я хотел бы использовать две разные реализации для DAO с тестовой рамкой Spring.

src.main.java

.businessobjects
   \-User.java
.dao
   \-IUserDAO.java
.daojpa
   \-UserDAO.java
.daohibernate
   \-UserDAO.java

Тестовый пружинный тест в:

src.test.java.base:

package base;

import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/hibernate-beans.xml")
@Transactional
public abstract class SpringTestCase {}

И здесьэто ошибка:

Причина: java.lang.IllegalStateException: указанное в аннотации имя компонента 'userDAO' для класса компонента [jpadao.UserDAO] конфликтует с существующим, несовместимым определением компонента с тем же именеми класс [jpaadao.UserDAO]

Я уже пытался переопределить автоматическую разводку, используя квалификаторы, например:

<bean class="jpaadao.UserDAO">
    <qualifier value="jpaa"/>
</bean>
<bean class="jpadao.UserDAO">
    <qualifier value="jpa"/>
</bean>

А затем в проводке тестового набора с помощью

@Autowired
@Qualifier("jpa")
private IUserDAO userDAO;

но ошибка не устранена.

Два вопроса:

  1. Как решить эту проблему с помощью конфигурации на основе аннотаций?
  2. Как выполнить тесты БЕЗ автопроводка и аннотации?

Ответы [ 4 ]

2 голосов
/ 09 июля 2010

Вы используете bean-компоненты без имен, так что Spring попытается придумать имя, это имя может основываться на аннотации @Component, которую вы, вероятно, используете в своем классе, но это также может быть вербальная версия вашего неквалифицированное имя класса вашего компонента (в обоих случаях они получатся равными, и это приведет к возражению Spring).

Кроме того, кажется, что вы смешиваете сканирование компонентов и конфигурацию xml таким образом, который кажется мне немного странным.

Есть много выходов из этого, но наиболее чисто вы бы использовали только один компонент, реализующий контракт, который вы пытаетесь выполнить. Если вам нужны разные реализации, вы должны дать им разные и более различительные имена:

<bean id="jpaUserRepository" class="..JpaUserRepository"/>

Это даст вам более полезное ведение журнала, даже если имена бинов никогда не используются, потому что вы полагаетесь на автоматическое подключение.

1 голос
/ 11 июля 2010
  1. Делайте то, что предложил Iwein: лучше называйте свои классы реализации (например, HibernateUserDao и JpaUserDao); или укажите уникальное имя компонента с помощью аннотации @Component или @Repository в ваших классах реализации UserDAO.
  2. В настоящее время вы не можете запускать тесты без автоматической разводки. Подробности смотрите в этом выпуске JIRA: https://jira.springsource.org/browse/SPR-6050

С уважением,

Сэм (автор Spring TestContext Framework)

p.s. Нет, проблема, с которой вы столкнулись, не связана с SPR-4524.

0 голосов
/ 08 июля 2010

У меня все работает! Однако я не верю, что это лучшая практика. Я просто исключил путь нежелательных DAO, написав в appContext.xml:

   <context:component-scan base-package="test">
        <context:exclude-filter type="regex" expression="test\.daohibernate.*"></context:exclude-filter>
    </context:component-scan>

Есть предложения? Может ли эта проблема быть связана с http://jira.springframework.org/browse/SPR-4524?

0 голосов
/ 08 июля 2010

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

...