今天需要开发一个暂时没有页面的功能,这样就不能通过普通的B/S访问去调用代码。以前把JUnit看的太小儿科,所以根本没有想到还能用它结合Srping来测试Service层或者Dao层的逻辑。
这里主要记录一下在使用JUnit+Spring+Maven遇到的问题和解决方法,以便日后深入学习。
首先使用JUnit4,创建JUnit类,具体方法不在赘述。
因为不是测试简单的几行Java程序,需要连接数据库和使用Spring配置,所以与通常JUnit的写法不一样,这里需要获取并启动Spring的容器。
这里先说明一下,本文没有使用SpringFrameWork提供的单元测试。所以需要手动获取ApplicationContext。可以写在@before的方法中。
ApplicationContext axt = new ClassPathXmlApplicationContext(new String[] {"classpath:applicationContextTest.xml"});
testClass= (testClass) axt.getBean("testClass");
这里有一个需要注意的地方,就是:
classpath:applicationContextTest.xml
和
classpath*:applicationContextTest.xml
这两个写法的区别在于第一种只会到classpath下面的相应路径加载配置文件。第二种如果在classpath下找不到的话,还会去classpath中的jar文件中去寻找,并且如果有多个满足条件的话可以全部加载。
好的,第一个问题出现了。运行Junit提示错误信息:“NoSuchBeanDefinitionException”。
不管是用名称还是用类型加载,都无法注入这个类。
原因是
这篇文章最后说到的:所使用到的类必须手动在xml文件中配置,不然将会发生类型不匹配的错误。
所以在配置文件中声明我要测试的bean。
<bean id="testClass" class="workFlowTest.testData.TestClass" autowire="default">
<property name="sqlSession" ref="sqlSession"></property>
</bean>
<!-- SqlSessionTemplate设置 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
<constructor-arg index="0" ref="sessionFactory" />
</bean>
在testClass中还有一个属性sqlSession。
@Autowired
private SqlSession sqlSession;
这个类的全限定名是
org.apache.ibatis.session.SqlSession
但是这个类是个接口,不能直接去注入,后来想到是不是Spring会有它的实现呢?果真在配置文件下面找到了id为sqlSession的这个类。
再次运行JUnit,又报错了:SqlException:Not Found Class:oracle.jdbc.driver.OracleDriver
只好从Maven仓库中添加依赖
<!-- 添加oracle jdbc driver -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.1.0</version>
</dependency>
这样才不报错,这个问题现在还没有弄明白,这个驱动类本来应该可以加载到的,因为项目都可以正常运行,只是用了JUnit后就必须要手动添加到Libraries中。这个问题还有待研究,有哪位知道的话还烦请留言告诉我,谢谢。
与此问题相似的还有Spring的事务管理,原来的写法就会报某个类找不到,因为事务不是测试必须,所以就先将那一段注释掉。
至此运行Junit,便可以测试Dao层内容。
总结:在使用JUnit进行Spring项目的测试时,最好新建测试专用的测试类,被测试类,以及启动Spring容器所需要的配置文件。