一、原因:
在使用了spring的web项目中,所有的对象都交给spring容器管理:比如dataSource,sqlSessionFactory,mapper代理对象,service对象等。这样的话,进行单元测试就变得很复杂,如下两种方式可以实现:
1。让测试类继承BeanFactoryAware,或者ApplicationContextAware,将容器本身注入进来,然后就可以获取容器中的对象进行单元测试。
2。还有就是spring与junit4的整合:
加入jar包:junit4jar包,spring-tes.jar,spring-xxx依赖jar包。
创建测试目录,测试包,测试类,
测试目录与src同级目录;测试包与src包名一致,测试类名:要测试的类+Test。
二、重点在测试类:两种方式去实现
1、自定义一个测试基类(也可以直接写这样的测试类),在基类中完成常用的注解配置,然后让测试类继承该类,可以省去很多重复的注解代码:
测试基类代码如下:
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
/*
* spring整合Junit4单元测试基类,
* 其他类实现该类可以省略一些注解配置。
* */
//使用junit4进行单元测试
@SuppressWarnings("deprecation")
@RunWith(SpringJUnit4ClassRunner.class)//使用junit4进行测试
//加载配置文件,可以指定多个配置文件,locations指定的是一个数组
@ContextConfiguration(locations={"classpath:spring/applicationContext-*.xml", "classpath:spring/springmvc.xml"})
//------------如果加入以下代码,所有继承该类的测试类都会遵循该配置,也可以不加,在测试类的方法上///控制事务,参见下一个实例
//这个非常关键,如果不加入这个注解配置,事务控制就会完全失效!
//@Transactional
//这里的事务关联到配置文件中的事务控制器(transactionManager = "transactionManager"),同时//指定自动回滚(defaultRollback = true)。这样做操作的数据才不会污染数据库!
//@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
//------------
//启动事务控制
@Transactional
//配置事务管理器,同时指定自动回滚
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
//加载配置文件,这里写你自己的spring配置文件的存放目录
public class BaseJunit4Test {
//进行测试时,将测试类继承该类
//注入service对象
//然后在方法上使用@Test,@RollBack,@Transaction等注解单独修饰
}
测试类代码如下:
public class ItemsServiceImplTest extends BaseJunit4Test{
@Autowired
private ItemsService itemsService;
@Test
public void testFindItemsList() throws Exception {
List<ItemsCustom> itemsList = itemsService.findItemsList();
System.out.println(itemsList);
}
}
2。另一种实现方式:spring4.2版本提供如下两个抽象类:
1。org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests //与事务无关的类
2。org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests //可以控制事务的类
将测试类继承上面两个抽象类中的一个:建议使用第二个,可以控制事务,也可以测试与事务无关的方法。
测试类代码如下:
/*
* 测试继承AbstractTransactionalSpringContextTests这个类
* 继承该类,可以测试进行事务控制,测试完成后自动回滚
* */
@RunWith(SpringJUnit4ClassRunner.class)
//locations:参数值因配置文件地址来改变
@ContextConfiguration(locations={"classpath:spring/applicationContext-*.xml", "classpath:spring/springmvc.xml"})
public class ItemsServiceImplTest1 extends AbstractTransactionalJUnit4SpringContextTests{
//注入service对象
@Autowired
private ItemsService itemsService;
@Test
//还可以加入@RollBack注解 @Transaction注解来对方法进行事务注解
public void testFindItemsList() throws Exception {
List<ItemsCustom> itemsList = itemsService.findItemsList();
System.out.println(itemsList);
}
}
常用注解:
@RunWith:这个是指定使用的单元测试执行类,这里就指定的是SpringJUnit4ClassRunner.class;
@ContextConfiguration:这个指定spring配置文件所在的路径,可以同时指定多个文件;
@Test标注在方法前,表示其是一个测试的方法 无需在其配置文件中额外设置属性.
@TransactionConfiguration(transactionManagert=”txMgr”,defaultRollback=false) //类级别的,需要在bean.xml中配置TransactionManager,事务管理器,否则会抛异常
@Transactional //类级别,或者方法级别的注解
在方法中主要使用的Annotation包括
@TestExecutionListeners({})—用于禁用默认的监听器 否着需要通过@contextconfiguration配置一个ApplicationContext;
@BeforeTransaction
@Before
@Rollback(true) //方法级别的,指定该方法测试完成后是否回滚