这两天的花费了一些时间在使用spring-mock进行spring的单元测试问题上,基本上对这个问题有了一个大概的了解,总结如下:
1、 测试普通的java类。
① 首先,要建立一个测试类继承org.springframework.test.AbstractTransactionalDataSourceSpringContextTests类。
必须继承该类主要是为了获得Spring的Context。得到了Context才能使测试得以进行。
※该类经过多层的继承关系后,也继承于junit.framework.TestCase。
② 继承①中提到的类就必须要override其中的方法getConfigLocations()。实现如下:
protected String[] getConfigLocations() {
//必要の配置ファイルを提出する
String[] config = new String[] {
"file:D:\\develop\\workspace\\lcl\\web\\WEB-INF\\entry-MenuDAO.xml"
};
return config;
}
该方法是为了读入spring的上下文信息,这样的话这个测试用例就可以直接使用spirng中定义的 bean了。
但是这里需要注意一个问题*,就是文件路径的问题,这里为了能够清楚地说明文件的 路径规则我引用了spring-mock官方的getConfigLocation方法说明
Subclasses must implement this method to return the locations of their config files. A plain path will be treated as class path location. E.g.: "org/springframework/whatever/foo.xml". Note however that you may prefix path locations with standard Spring resource prefixes. Therefore, a config location path prefixed with "classpath:" with behave the same as a plain path, but a config location such as "file:/some/path/path/location/appContext.xml" will be treated as a filesystem location.
③ 取得Spirng上下问中定义的bean的实例来进行单元测试这里有两种方法,
※一种是定义一个代测单元的对象,然后定义好get,set方法, AbstractTransactionalDataSourceSpringContextTests会自动根据Spring的上下文得到待测单元的具体实现。
private MenuDAO menuDAO ;
public MenuDAO getMenuDAO(){
return menuDAO ;
}
public void setMenuDAO ( MenuDAO menuDAO ){
this.menuDAO = menuDAO ;
}
※另外一种就是使用applicationContext.getBean("XXXDAO");的方法取得实例 XXXDAO xxxDAO = (XXXDAO)applicationContext.getBean("XXXDAO");
④ 接下来你就可以用这个bean的具体实现对相关方法进行unittest了。
注:
♀按照框架规定:编写的所有测试类,必须继承自junit.framework.TestCase类;里面的测试方法,命名应该以test开头,必须是public void 而且不能有参数;而且为了测试查错方便,尽量一个testXXX方法对一个功能单一的方法进行测试;使用assertEquals等junit.framework.TestCase中的断言方法(实际是junit.framework.Assert中的方法,TestCase继承了Assert。)来判断测试结果正确与否。
♀请注意Eclips中弹出窗口的一个细节,在绿条下面有Errors、Failures统计。这两者有何区别呢?
Failures作为单元测试所期望发生的错误,它预示你的代码有bug,不过也可能是你的单元测试代码有逻辑错误(注意是逻辑错误)。Errors不是你所期待的,发生了Error你可以按照下面的顺序来检查:
检查测试所需的环境,如:数据库连接
检查单元测试代码
检查你的系统代码
♀可以将所有的测试用例都放到一个TestSuit中进行测试,这样对于有修改之后的再测试非常的方便。
2、 对于View的测试。
① 首先,针对要测试的view创建一个测试类XXXViewTest,该类要继承于org.junit.framework.TestCase。
② 做成main方法:
public static void main(String[] args) {
junit.textui.TestRunner.run(XXXViewTest.class);
}
③ 需要实现的方法
setUp()方法:
protected void setUp() throws Exception {
ApplicationContext context = new FileSystemXmlApplicationContext(
new String[] {
"file:D:\\develop\\workspace\\lcl\\web\\WEB-INF\\applicationContext.xml"
, "file:D:\\develop\\workspace\\lcl\\web\\WEB-INF\\lcl-servlet.xml"
});
BeanFactory beanFactory = (BeanFactory) context;
controller = (Controller) beanFactory.getBean("entryMenuController");
super.setUp();
}
该方法是在run()之前运行,主要是得到Context,列出必要的配置文件。
tearDown()方法:
protected void tearDown() throws Exception {
super.tearDown();
}
该方法是在run()之后运行。
④ 测试方法:
public void testOnSubmitSuccess(){
MockHttpServletRequest req = new MockHttpServletRequest("POST","menulist.html");
req.addParameter("navigator.currentPage","4") ;
ModelAndView mv = null;
try {
mv = controller.handleRequest(req,new MockHttpServletResponse());
} catch (Exception err) {
err.printStackTrace();
}
//遷移先のチェック
assertEquals("viewName","common/menulist",mv.getViewName());
}
该方法中需要注意的是:如何得到request。之后就可以进行构造请求来完成测试了。
⑤ 以上です。
注:いろいろなassertメソッドについて、Junitのヘルプをご参照して下さい。