【问题标题】:how to integration test a DAO built with spring + iBatis如何集成测试使用 spring + iBatis 构建的 DAO
【发布时间】:2009-11-10 02:35:33
【问题描述】:

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

我想做的事:我只是想为我的 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());
        }
    } 
}

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

我的测试

public class MyDAOTests extends TestCase {

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

 }
}

我试图在这段代码 sn-p 中呈现整个问题。测试失败,因为它无法连接到数据库……因为它在容器之外。我知道可以修复设计以更好地利用依赖注入。您能否根据这个 sn-p 向我展示可以进行哪些改进以使测试能够正常工作?

我一直在努力解决这个问题,非常感谢一些帮助。

PS:我不得不使用setSqlMapClientTemplate(),因为我希望调用我的DAO 很简单MyDAO myd = new MyDAO() 我不想为我的每个DAO 制作接口。

【问题讨论】:

  • 为什么你的 Abstract 类有硬连线的 JNDI 名称?只需使用 Spring 注入即可。
  • 这看起来像是一个实际上并不了解 Spring 的人为 Spring 编写的应用程序。我为你感到难过。
  • 我为自己感到难过……因为对 spring 的了解不够好,无法自己更正这段代码。错在我...

标签: java spring junit dao ibatis


【解决方案1】:

这里有很多问题。

首先,在您的小示例中,我计算了 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 进行测试。

【讨论】:

  • First:明白这很糟糕,但我应该保留它的地方是什么?你说注入正在使用弹簧。这到底是什么意思呢?在这三个引用中,我是否在某处使用弹簧注射?我该怎么做? 第二:我正在更改遗留代码。有很多代码在调用 DAO 方法。如果我确实遵循 spring 成语,那么我将不得不回去改变 DAO 的调用方式。 第四:我可以使用 DriverManager 数据源代替 MyServiceLocator,但是 .getBean("MapClient"); 呢?如果没有容器,我将如何获得它?非常感谢
  • “我正在更改遗留代码” - 那么也许 Spring 不是您的情况的答案。你想解决什么问题?
  • 在遗留代码中,我将 JDBC 代码转换为 iBatis。如果我从我的 Abstract 类中取出 JNDI 名称,那么我将不会使用 MyServiceLocator。但是,我如何在 MyAbstract 类中获取 DataSource 呢?我阅读了 spring 的第 11 章,但他们没有展示如何将 JNDI 名称作为 bean 获取并从中获取数据源..
  • 你提供一个setter - setDataSource(DataSource) - 并允许它被上下文(xml文件)注入
  • 那么重点是您的 DAO 没有绑定到特定的数据源或 JNDI 字符串,从而可以/轻松地提供不同的值、模拟对象等进行测试。这是 Spring 的主题——将依赖项注入到一个类中,而不是一个类出去寻找它需要的东西
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 2013-01-16
  • 2012-10-17
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多