如何集成测试使用spring + iBatis构建的DAO

时间:2009-11-10 02:35:34

标签: java spring junit dao ibatis

我问question,其标题可能会产生误导,所以我会尝试用更详细的东西再次提问。 (我知道问题似乎很长但请耐心等待我)

我正在尝试做什么:我只想为我的DAO编写测试用例并使其正常工作。我知道我的DAO在容器(app服务器)内工作正常但是从测试用例调用DAO时它不起作用。我认为因为它在容器之外。

我的spring-for-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 个答案:

答案 0 :(得分:6)

这里有很多问题。

首先,我在小例子中计算JNDI查找字符串的三次引用。如果可能,DRY会告诉你写一次并参考它。

其次,我不太欣赏你的DAO。这真的是你在写什么,还是这只是一个例子?我不认为这是春天的成语。没有界面。没有一个,你将如何进行声明性交易?我建议更仔细地查看Spring docs for iBatis

第三,我建议使用JUnit 4.4,或者更好的是,使用TestNG成语 - 注释。另请查看Spring @ContextConfiguration以在setUp中注入所需的bean。

第四,您的DAO无法正常运行,因为您需要运行JNDI查找服务,并且您无法获得没有容器的服务。答案是为测试提供DriverManager数据源。

更新:尝试以下操作:使用Spring idiom for iBatis。如果遗产阻止你这样做,那么Spring可能不是你的答案。

完成此操作后,您所要做的就是覆盖数据源应用程序上下文,以便使用DriverManager而不是JNDI进行测试。