Java 如何集成测试用spring+;伊巴蒂斯

Java 如何集成测试用spring+;伊巴蒂斯,java,spring,junit,dao,ibatis,Java,Spring,Junit,Dao,Ibatis,我问了一个标题,这个标题可能有误导性,所以我想用更详细的内容再问一次这个问题。(我知道问题似乎很长,但请耐心等待) 我要做的事情:我只想为我的DAO编写一个测试用例并使其工作。我知道我的DAO在容器(应用服务器)中工作得很好,但是当从测试用例调用DAO时,它不工作。我想是因为它在容器外面 我的spring-for-iBatis.xml中的东西 <bean id="IbatisDataSourceOracle" class="org.springframework.jndi.JndiObje

我问了一个标题,这个标题可能有误导性,所以我想用更详细的内容再问一次这个问题。(我知道问题似乎很长,但请耐心等待)

我要做的事情:我只想为我的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>
我的刀:

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创建接口

这里有很多问题

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

第二,我不太欣赏你的刀。这真的是你在写的吗,还是这只是一个例子?我认为这不是春天的成语。没有接口。如果没有声明性事务,您将如何执行声明性事务?我建议你更仔细地看一下

第三,我建议使用JUnit4.4,或者更好的是,使用TestNG习惯用法注释。还可以查看Spring@ContextConfiguration来注入安装程序中所需的bean

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

更新:这里有一个尝试的想法:使用。如果遗产阻止你这么做,也许春天不是你的答案


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

这里有很多问题

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

第二,我不太欣赏你的刀。这真的是你在写的吗,还是这只是一个例子?我认为这不是春天的成语。没有接口。如果没有声明性事务,您将如何执行声明性事务?我建议你更仔细地看一下

第三,我建议使用JUnit4.4,或者更好的是,使用TestNG习惯用法注释。还可以查看Spring@ContextConfiguration来注入安装程序中所需的bean

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

更新:这里有一个尝试的想法:使用。如果遗产阻止你这么做,也许春天不是你的答案


一旦您这样做,您所要做的就是覆盖数据源应用程序上下文,以便在测试中使用DriverManager而不是JNDI。

为什么您的抽象类将JNDI名称硬连接到其中?只需使用Spring注入它。这看起来像是一个不了解Spring的人为Spring编写的应用程序。我为你感到难过。我为自己感到难过…因为我对spring了解不够,无法自己更正这段代码。这是我的错…为什么你的抽象类中硬连接了JNDI名称?只需使用Spring注入它。这看起来像是一个不了解Spring的人为Spring编写的应用程序。我为你感到难过。我为自己感到难过…因为我对spring了解不够,无法自己更正这段代码。错误是我的…首先:明白这很糟糕,但我应该保留它的地方是什么?你说注射用的是弹簧。这到底是什么意思?在三个citings中,我是否在某处使用spring injection?我该怎么做?第二:我正在更改遗留代码。有很多代码正在调用DAO方法。如果我真的遵循春天的成语,那么我将不得不回去改变道的命名方式。第四:我可以使用DriverManager数据源而不是MyServiceLocator,但是.getBean(“MapClient”)呢;?没有集装箱我怎么能拿到?非常感谢“我正在更改遗留代码”——那么也许Spring并不能解决您的问题。您试图解决什么问题?在遗留代码中,我将JDBC代码转换为iBatis中的代码。如果我从抽象类中去掉JNDI名称,那么我就不会使用MyServiceLocator。但是,如何在MyAbstract类中获取数据源呢?我读了spring的第11章,但他们没有说明如何将JNDI名称作为bean获取并从中获取数据源。您提供了一个setter-setDataSource(datasource)-并允许它被上下文(xml文件)注入。那么,关键是DAO没有绑定到特定的数据源或JNDI字符串,使提供不同的测试值、模拟对象等成为可能/容易。这是Spring的主题——将依赖项注入到类中,而不是一个类出去寻找它需要的东西。首先:理解这很糟糕,但我应该保留它的位置是什么?你说注射用的是弹簧。这到底是什么意思?在三个citings中,我是否在某处使用spring injection?我该怎么做?第二:我正在更改遗留代码。有很多代码正在调用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());

 }
}