这两天的花费了一些时间在使用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のヘルプをご参照して下さい。
|