Java 如何集成测试用spring+;伊巴蒂斯
我问了一个标题,这个标题可能有误导性,所以我想用更详细的内容再问一次这个问题。(我知道问题似乎很长,但请耐心等待) 我要做的事情:我只想为我的DAO编写一个测试用例并使其工作。我知道我的DAO在容器(应用服务器)中工作得很好,但是当从测试用例调用DAO时,它不工作。我想是因为它在容器外面 我的spring-for-iBatis.xml中的东西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
<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());
}
}