spring4.3与Junit412整合:
Junit的好处在这就不必啰嗦了,本文章主要根据自己整合junit时遇到的坑跟大家分享一下,让朋友们少踩坑。
注意:spring4.3与Junit4.11会有冲突:运行测试用例时会报:initializationError: java.lang.Exception:No tests found matching[]…
本人的项目是非maven项目,而且使用的是jndi的方式连接数据库,相对于使用c3p0或者durids繁琐一些,以后再对maven项目做一个junit的讲解。
一、配置文件
单元测试不再需要启动服务器才能跑代码了,但是配置文件还是少不了的。
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
<!-- 有了上面的driven后config可以不配,因为driven也会帮忙注入 -->
<context:annotation-config/>
<!-- 扫描springmvc注解的类生成对应的bean,如@Service @Repository @Controller等注解 直接扫上层包即可 -->
<context:component-scan base-package="com.pab"></context:component-scan>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 定义事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"/>
<property name="dataSource" ref="dataSource"</property>
</bean>
<!-- 数据源 项目使用的是JNDI的方式连接数据库,JNDI方式需要启动服务到tomcat的service.xml中获取对应的配置才能连接数据库,但我们单元测试
不需要启动服务,所以无法连接,解决方法可以配置一个jndi.xml文件,在运行单元测试前去加载即可,见后面的讲解 -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/hello"></property><!-- 注意这里的value值,后面会用到 -->
</bean>
</beans>
刚才说过需要配置一个jndi用于运行测试用例时加载,这是jndi不启动服务器却获得数据源的重要一步。(如果是c3p0或者durids都不需要这个文件)
jndi.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- DriverManagerDataSource 该数据源实现类并不提供数据池机制,只要有连接就会创建一个connection,用于单元测试没问题 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@10.52.84:8888:oradb"/>
<property name="username" value="shitailong"></property>
<property name="password" value="888888"/>
</bean>
</beans>
注意:这两个xml文件最好新建一个Source Floder类型的源文件放进去,类路径下能确保加载得到。
二、创建一个基础测试类,用于加载配置文件、配置session等,以后每个测试类只要继承该类即可做测试。
BaseJunit.java
package cn.wolfcode;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringJUnit4ClassRunner.class) //指定运行的测试类 该类在spring-test里,有时无法引入只能手工敲了
@ContextConfiguration(locations= {"classpath*:/applicationContext.xml"})//spring-test里的类,这个很重要,把配置文件里的内容加载到容器中
@WebAppConfiguration
@Transactional(transactionManager="transactionMananger") //这里的事务即是取applicationContext.xml的事务
@Rollback //默认为true 即事务回滚
public class BaseJunit {
这里注释的代码主要使用spring里的mockmvc模拟session、request、map等,如果不需要到可以不要
// @Autowired
// protected WebApplicationContext wac;
// protected MockMvc mockMvc;
// protected MockHttpSession session;
// protected MockHttpServletRequest request;
// protected ModelMap map;
@BeforeClass //Junit里的方法,在整个单元测试运行之前先运行,所以可以用于加载xml等文件操作,这里加载jndi.xml,
public static void beforeClass() throws Exception{ //这样就解决了JNDI连接方式不启动tomcat无法连接数据库的问题
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath*:/jndi.xml");//加一个*会整个项目去找这个xml,只要能加载到不加也是可以的
DataSource ds = (DataSource) app.getBean("dataSource"); //我们jndi.xml里配置的数据源id="dataSource"
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder.bind("java:com/env/jdbc/hello",ds);//数据源与applicationContext.xml里的jndiName的value绑定
builder.activate();
}
@Before //每个测试用例执行前都会执行一次
public void setup() { //这里使用MockMvc构造各种session等,这个看个人需要吧
// this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
// this.session = new MockHttpSession();
// this.request = new MockHttpServletRequest();
// this.map = new ModelMap();
// User us = new User(); //用户实体类
// us.setUmname("lixiaolong");
// session.setAttribute("user",us);
}
}
到此为止,spring与junit的整合算是完成了,后面写单元测试只要继承这个基础测试类即可。
注意:如果使用到mockmvc,则spring版本必须在spring3.2及以上,mockmvc是在spring3.2才集成过来的。
下一篇将使用具体的案例和大家分享一下JUnit和Mockmvc的使用