spring 环境下 的单元测试 spring3+junit4.8 各种测试方法写法
环境 spring 3 + junit4.8
第一种方法 老版本里常用 AbstractTransactionalDataSourceSpringContextTests
首先引入 junit4.8jar包 ,一般eclipse自带的library里是有的,可以直接引入
spring方面要引入 org.springframework.test-3.0.5.RELEASE.jar包
创建一个basetestcase类
继承AbstractTransactionalDataSourceSpringContextTests
public abstract class BaseTestCase extends AbstractTransactionalDataSourceSpringContextTests{
protected static final Logger log = LoggerFactory.getLogger(BaseTestCase.class);
/**
* spring配置文件的路径前缀
*/
protected static final String CONFIG_PREFIX = "classpath:conf/spring";
/**
* 定义默认的Spring Context的主文件路径.
*/
protected static final String DEFAULT_MAIN_CONTEXT = "classpath:conf/spring/applicationContext.xml";
protected static final String LEADIN_CONTEXT = "classpath:conf/spring/leadinServiceContext.xml";
/**
* 定义除主文件外所有的Spring Context文件集合的路径.
*/
protected static final String All_CONTEXT = "classpath:conf/spring/*.xml";
/**
* @see AbstractTransactionalDataSourceSpringContextTests#getConfigLocations()
*/
@Override
protected String[] getConfigLocations() {
// 设置AUTOWIRE_BY_NAME ,因为Spring的测试基类默认为BY_TYPE,在有多个相同类型的Bean时冲突.
// 或者取消setter函数,自行用applicationContext.getBean()来显式查找Bean.
setAutowireMode(AUTOWIRE_BY_NAME);
// 默认载入所有的spring配置的bean,在子类可重载此函数以减少载入的applicaitonContext.xml,加快测试速度.
List<String> contexts = new ArrayList<String>();
contexts.add(DEFAULT_MAIN_CONTEXT);
contexts.add(LEADIN_CONTEXT);
contexts.add("classpath:conf/spring/baseCommonDaoContext.xml");
contexts.add("classpath:conf/spring/baseCommonServiceContext.xml");
contexts.add("classpath:conf/spring/baseContext.xml");
contexts.add("classpath:conf/spring/baseFrameContext.xml");
contexts.add("classpath*:mq-server-bootstrap-config.xml");
List<String> neededContexts = Arrays.asList(getNeededConfigLocations());
contexts.addAll(neededContexts);
return contexts.toArray(new String[] {});
}
/**
* 子类只需重写此方法
*/
protected abstract String[] getNeededConfigLocations();
protected Object getBean(String name) {
return applicationContext.getBean(name);
}
}
测试类KgEnrollDaoTest
public class KgEnrollDaoTest extends BaseTestCase {
@Autowired
private KgEnrollTimeDao kgEnrollTimeDao;
@Override
protected String[] getNeededConfigLocations() {
return new String[] { "classpath:/conf/spring/KgEnrollDaoContext.xml" };
}
public void testsave(){
String unitId = "1111";
String enrollyear = "1111";
int i = kgEnrollTimeDao.checkExists(unitId, enrollyear);
System.out.println(i);
}
}
以上方法可以用来测试service和dao
getNeededConfigLocations 用来引入需要测试的xml配置文件
但是spring3.0里不建议使用这个方法了 AbstractTransactionalDataSourceSpringContextTests
那么用什么来替代呢
可以用AbstractTransactionalJUnit4SpringContextTests来代替
package net.zdsoft.test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.sql.DataSource; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) /** * 定义默认的Spring Context的主文件路径.以及你需要测试的配置文件 */ @ContextConfiguration(locations = {"classpath:conf/spring/applicationContext.xml","classpath:/conf/spring/testContext.xml"}) public class MyTestCase extends AbstractTransactionalJUnit4SpringContextTests{ @Test public void testGetTeacher(){ System.out.println("1"); TestDao testDao= (TestDao)this.applicationContext.getBean("testDao"); System.out.println(testDao.getNormalEmployee("B6EE1FEBB344E730E040817B11FE7186",null).size()); } }
如果不使用 applicationContext.getBean,可以使用@Autowired注解注入
import javax.sql.DataSource; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) /** * 定义默认的Spring Context的主文件路径.以及你需要测试的配置文件 */ @ContextConfiguration(locations = {"classpath:conf/spring/applicationContext.xml","classpath:/conf/spring/testContext.xml"}) public class MyTestCase extends AbstractTransactionalJUnit4SpringContextTests{ @Autowired private TestDao testDao; @Test public void testGetTeacher(){ System.out.println(testDao.getNormalEmployee("B6EE1FEBB344E730E040817B11FE7186",null).size()); } }
与AbstractTransactionalDataSourceSpringContextTests所写的方法的区别在于 最上面这种方式通过抽象类实现了主配置文件applicationcontext.xml以及一些系统必须的配置文件的加载,并提供了一个抽象方法供子类加入自己想要测试的bean所在的配置文件,只要写一个公共的抽象类 子类集成即可
AbstractTransactionalJUnit4SpringContextTests的方式降低了通用性
为了提供类似的通用性 我写了一个方法,但不确认完全正确 经供参考
同样写了一个类似方法1的抽象类
package net.zdsoft.test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.sql.DataSource; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) /** * 定义默认的Spring Context的主文件路径. */ @ContextConfiguration(locations = {"classpath:conf/spring/applicationContext.xml"}) //@ContextConfiguration(locations = {"classpath:conf/spring/applicationContext.xml","classpath:/conf/spring/personnelContext.xml"}) public abstract class BaseCase extends AbstractTransactionalJUnit4SpringContextTests{ @Before public void init(){ //初始化spring List<String> locations = new ArrayList<String>(); locations.add("classpath:conf/spring/applicationContext.xml"); //加载子类的配置文件 locations.addAll(Arrays.asList(getExLoactions())); ApplicationContext context = new FileSystemXmlApplicationContext(locations.toArray(new String[0])); super.setApplicationContext(context); super.setDataSource((DataSource)context.getBean("dataSource")); } /** * 提供子类覆盖 * 设置子类要加载的配置文件 * @return */ public abstract String[] getExLoactions(); }
通过@Before注解 再次加载applicationcontext (记得要把主要配置文件和一些系统必须的再次加入)
把子类覆盖的配置文件也加载进来
然后重置测试类中的applicationcontext的值
package net.zdsoft.test; import org.junit.Test; import net.zdsoft.eis.personnel.info.dao.EmployeeDao; public class TestDao extends BaseCase{ @Override public String[] getExLoactions() { return new String[]{"classpath:/conf/spring/testContext.xml"}; } @Test public void testGetTeacher(){ System.out.println("1"); TestDao testDao = (TestDao)this.applicationContext.getBean("testDao"); System.out.println(testDao.getNormalEmployee("B6EE1FEBB344E730E040817B11FE7186",null).size()); } }
这种方式只是为了方便其他人调用这个公共类测试,其效率由于第一次加载后会再次加载所以会比较低,而且不知道会不会引起其他错误,欢迎大牛指正