1

我问了一个问题,其标题可能具有误导性,所以我将尝试用更详细的内容再次提出这个问题。(我知道问题似乎很长,但请多多包涵)

我正在尝试做的事情:我只是想为我的 DAO 编写一个测试用例并让它工作。我知道我的 DAO 在容器(应用程序服务器)内工作正常,但是从测试用例调用 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());
        }
    } 
}

我的道:

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));
        }
}

我的测试

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 制作接口。

4

1 回答 1

6

这里有很多问题。

首先,我在您的小示例中计算了 JNDI 查找字符串的三个引用。DRY 会告诉你写一次并在可能的情况下参考它。

其次,我不太欣赏你的 DAO。这真的是你在写的,还是只是一个例子?我不认为这是春天的成语。没有界面。如果没有声明式事务,你将如何进行?我建议更仔细地查看 iBatis 的 Spring 文档。

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

第四,您的 DAO 无法工作,因为您需要运行 JNDI 查找服务,而没有容器就无法获得。答案是为您的测试提供一个 DriverManager 数据源。

更新:这是一个尝试的想法:使用Spring idiom for iBatis。如果遗留问题阻止您这样做,那么 Spring 可能不是您的答案。

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

于 2009-11-10T02:50:56.770 回答