Как провести интеграционное тестирование DAO, созданной с помощью Spring + iBatis - PullRequest
1 голос
/ 10 ноября 2009

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

Что я пытаюсь сделать : я просто хочу написать контрольный пример для моего DAO и заставить его работать. Я знаю, что мой DAO работает нормально внутри контейнера (сервера приложений), но при вызове DAO из тестового примера ... он не работает. Я думаю, потому что это за пределами контейнера.

Материал в моей весне для iBatis.xml

<bean id="IbatisDataSourceOracle" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/RSRC/my/db/oltp"/>
</bean>
<bean id="MapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="classpath:sql-map-config-oracle.xml"/>
  <property name="dataSource" ref="IbatisDataSourceOracle"/>
 </bean>

Материал в моем sql-map-config-oracle.xml

<sqlMapConfig>
   <settings enhancementEnabled="true" useStatementNamespaces="true" />
 <transactionManager type="JDBC">
  <dataSource type="JNDI">
   <property name="DataSource" value="jdbc/RSRC/my/db/oltp"/>
  </dataSource>
 </transactionManager>
         <sqlMap resource="mymapping.xml"/>
</sqlMapConfig>

мой абстрактный класс:

public abstract MyAbstract {
    public SqlMapClientTemplate getSqlTempl() SQLException{
        public static final String ORCL = "jdbc/RSRC/PIH/eiv/oltp";
        try {
            ApplicationInitializer.getApplicationContext().getBean("MapClient");
            SqlMapClient scl = (SqlMapClient) ApplicationInitializer.getApplicationContext().getBean("MapClient");
            DataSource dsc = (DataSource) MyServiceLocator.getInstance().getDataSource(ORCL);
            return new SqlMapClientTemplate (dsc, scl);
        }
        catch (NamingException e)
        {
            log.error(ne.getMessage(), e);
            throw new SQLException("some error here: " + e.getMessage());
        }
    } 
}

мой DAO:

public class MyDAO extends MyAbstract{
 public AnObject getSomething(String id)
        {
        HashMap myMap = new HashMap();
        myMap.put("id", id);
        try {
            setSqlMapClientTemplate(getSqlTempl());
        }
        catch (SQLException ne)
        {
            log.error (ne.getMessage(), ne);
        }
        getSqlMapClientTemplate().queryForList("mymapping.someproc", myMap);
        return AnObject ((List)myMap.get("firstresult").get(0));
        }
}

Mytests

public class MyDAOTests extends TestCase {

 public void testMyDAO ()
 {
  MyDAO myd = new MyDAO();
  AnObject ano = myd.getSomething("15");
  assertEquals("1500", ano.getContentId());

 }
}

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

Я боролся с этим и был бы очень признателен за помощь.

PS: мне пришлось использовать setSqlMapClientTemplate(), потому что я хочу, чтобы вызов в мой DAO был просто MyDAO myd = new MyDAO() Я не хочу создавать интерфейс для каждого из моих DAO.

1 Ответ

6 голосов
/ 10 ноября 2009

Здесь много проблем.

Во-первых, я посчитал три цитаты строки поиска JNDI в вашем небольшом примере. DRY скажет вам написать это один раз и обратиться к нему, если это возможно.

Во-вторых, я не очень ценю ваш DAO. Это действительно то, что вы пишете, или это только пример? Я не думаю, что это идиома весны. Там нет интерфейса. Как вы будете делать декларативные транзакции без таковой? Я бы порекомендовал взглянуть на документы Spring для iBatis более внимательно.

В-третьих, я бы рекомендовал использовать JUnit 4.4 или, еще лучше, идиому TestNG - аннотации. Также проверьте Spring @ContextConfiguration, чтобы добавить bean-компоненты, которые вам нужны в setUp.

В-четвертых, ваши DAO не могут работать, потому что вам нужна запущенная служба поиска JNDI, и вы не можете получить ее без контейнера. Ответ заключается в том, чтобы иметь источник данных DriverManager для ваших тестов.

ОБНОВЛЕНИЕ: Вот идея, которую стоит попробовать: Используйте идиому Spring для iBatis . Если наследие мешает вам сделать это, возможно, Spring не ваш ответ.

После того, как вы это сделаете, все, что вам нужно сделать, это переопределить контекст приложения источника данных, чтобы использовать DriverManager вместо JNDI для вашего теста.

...