Spring-Mock--用于Spring 的单元测试
来源:互联网 发布:歌词编辑软件 编辑:程序博客网 时间:2024/05/17 23:59
Spring 的 mock 组建主要分3部分:
1. JNDI
The org.springframework.mock.jndi package contains animplementation of the JNDI SPI, which is useful for setting up asimple JNDI environment for test suites or stand-aloneapplications. If, for example, JDBC DataSources get bound to thesame JNDI names in test code as within a J2EE container, bothapplication code and configuration can be reused in testingscenarios without modification.
2. Servlet API
The org.springframework.mock.web package contains a comprehensiveset of Servlet API mock objects, targeted at usage with Spring'sWeb MVC framework, which are useful for testing web contexts andcontrollers. These mock objects are generally more convenient touse than dynamic mock objects (e.g., EasyMock) or existing ServletAPI mock objects (e.g., MockObjects).
3. Portlet API
The org.springframework.mock.web.portlet package contains a set ofPortlet API mock objects, targeted at usage with Spring's PortletMVC framework.
项目中主要用到的是2. ServeltAPI(org.springframework.mock.web),可以方便的mock出httprequest,httpsession等对象。
Spring Mock类简介
Mock对象是一个术语,原来主要流行于eXtreme程序员和JUnit小组中。在单元测试上下文中,一个mock对象是指这样的一个对象——它能够用一些“虚构的占位符”功能来“模拟”实现一些对象接口。在测试过程中,这些虚构的占位符对象可用简单方式来模仿对于一个组件的期望的行为和结果,从而让你专注于组件本身的彻底测试而不用担心其它依赖性问题。
Spring从J2EE的Web端为每个关键接口提供了一个mock实现:
MockHttpServletRequest—几乎每个单元测试中都要使用这个类,它是J2EEWeb应用程序最常用的接口HttpServletRequest的mock实现。
MockHttpServletResponse—此对象用于HttpServletResponse接口的mock实现。
MockHttpSession—这是另外一个经常使用的mock对象(后文将讨论此类在会话绑定处理中的应用)。
DelegatingServletInputSt
DelegatingServletOutputS
总之,在实现你自己的测试控制器时,上面这些对象是最为有用的。然而,Spring也提供了下列相应于其它不太常用的组件的mock实现(如果你是一个底层API开发者,那么你可能会找到其各自的相应用法):
MockExpressionEvaluator—这个mock对象主要应用于你想开发并测试你自己的基于JSTL的标签库时。
MockFilterConfig—这是FilterConfig接口的一个mock实现。
MockPageContext—这是JSPPageContext接口的一个mock实现。你会发现这个对象的使用有利于测试预编译的JSP。
MockRequestDispatcher—RequestDispatcher接口的一个mock实现,你主要在其它mock对象内使用它。
MockServletConfig—这是ServletConfig接口的一个mock实现。在单元测试某种Web组件(例如Struts框架所提供的Web组件)时,要求你设置由MockServletContext所实现的ServletConfig和ServletContext接口。
那么,我们该如何使用这些mock对象呢?我们知道,HttpServletRequest是一个持有描述HTTP参数的固定值的组件,而正是这些参数驱动Web组件的功能。MockHttpServletRequest,作为HttpServletRequest接口的一个实现,允许你设置这些不可改变的参数。在典型的Web组件测试情形下,你可以实例化这个对象并按如下方式设置其中的任何参数:
//指定表单方法和表单行为
MockHttpServletRequest request = newMockHttpServletRequest("GET", "/main.app");
request.addParameter("choice",expanded);request.addParameter("contextMenu", "left");
同样地,你可以实例化并全面地控制和分析HttpResponse和HttpSession对象。接下来,让我们简要观察Spring所提供的特定的JUnit框架扩展。
二、普通Web测试情形
在此,我们将回顾测试Web组件的普通情形以及怎样在其中使用Spring的mock对象和JUnit框架扩展。
(一)确定一个正确的视图
基于输入参数生成正确的视图可能是在操作一个Web应用程序时最普通的功能。在Spring MVC的上下文中,这意味着SpringMVC将基于参数的状态返回某种ModelAndView对象。你可以通过简单地利用如下的Mock对象以一个常规JUnit测试方式来测试这项功能:
public void final testGettingToDetails throws Exception{ MyController myController = newMyController(); myController.setDetailsView( detailsViewName ); MockHttpServletRequest request = newMockHttpServletRequest(); MockHttpServletResponse response = newMockHttpServletResponse(); request.setMethod("POST"); request.addParameter("viewDetails","true"); ModelAndView modelAndView =myController.handleRequest(request, response); assertEquals("Incorrect view name",detailsViewName,modelAndView.getViewName());}
既然控制器很可能会利用一些服务对象来决定结果视图,那么你还可以定制控制器中所用的这些mock服务对象。关于利用定制对象的更多资料,请参考mockobjects.com。
(二)会话相关的操作
对于任何J2EEWeb应用程序来说,另一个必须实现的操作是HttpSession绑定处理。例如,SpringMVC可能需要决定是否一个对象处于会话中及其具体状态以便产生正确的结果。你可以利用MockHttpSession对象和JUnit框架测试这种情形。请参考如下的代码片断:
public void testInvokesCorrectMethodWithSession() throws Exception {TestController cont = newTestController();MockHttpServletRequest request = newMockHttpServletRequest("GET", "/invoiceView.app");request.setSession(newMockHttpSession(null)); HttpServletResponse response = newMockHttpServletResponse(); ModelAndView mv =cont.handleRequest(request, response); assertTrue("Invoked loggedIn method",cont.wasInvoked("loggedIn")); assertTrue("view name is",mv.getViewName().equals("loggedIn")); assertTrue("Only one method invoked",cont.getInvokedMethods() == 1);//测试控制器但是不使用会话 request = newMockHttpServletRequest("GET", "/invoiceView.app"); response = newMockHttpServletResponse(); try { cont.handleRequest(request,response); fail("Should have rejected requestwithout session"); } catch (ServletException ex){//在此加入期盼的异常处理}}
(三)转发和重定向
一个SpringMVC组件执行的操作能够导致转发或重定向到另一个URL。如果你的目标是分析转发或重定向的结果,那么你可以测试这一情形—通过分析MockHttpResponse对象并进而确定有哪些内容包含在它的重定向或转发值中,如下所示:
String responseString =((MockHttpServletResponse)httpResponse).getForwardedUrl();
assertEquals( "Did not forward to theexpected URL", responseString, expectedString);
三、生成正确的二进制输出
如何确定你有多少次必须实现“View asPDF”这一功能?下面的JUnit代码片断使用mock输出流对象实现这一功能的正确测试:
public void testPDFGeneration() throwsException { MockHttpServletRequest request = newMockHttpServletRequest(); MockHttpServletResponse response = newMockHttpServletResponse(); viewInvoiceAsPDFController.handleRequest( request, response ); byte[] responsePDFValues =response.getContentAsByteArray(); byte[] expectedPDFValues =loadBytesFromTestFile(); assertTrue( "Did not generate expectedPDF content.", Arrays.equals(responsePDFValues,expectedPDFValues));}
注意,在此你的控制器ViewInvoiceAsPDFControll
四、事务性单元测试
到目前为止,你已看到了相对简单的JUnit测试—它仅发生在用mock对象支持的一个控制器的上下文中。但是,如果测试一个Web组件只有在一个事务性上下文(例如,通过依赖性注入与Hibernate集成到一起)中才有意义的情况又会怎么样呢?不必担心,SpringMVC为JUnit框架提供了一个体面的扩展集合—它能准确地提供依赖性注入和事务安全测试(也就是,任何更新在测试完成后都将被回滚)。
测试步骤:
让我们看一种假想的情形—你要实现一个组件(例如MyTransactionalControlle
1.创建一个定制的JUnit类(MyTransactionalControlle
importorg.springframework.test.AbstractDependencyInject
public classMyTransactualControllerT
public class.
2.为了实现从Spring内置的单元测试中发现Spring管理的bean,你需要重载getConfigLocations()方法并且返回上下文文件位置的String数组,请看如下:
protected abstract String[]getConfigLocations(){ return new String[]{"classpath:/test/spring-context.xml"};}
3.拥有该类的一个测试属性及其相关联的getter和setter。由于AbstractTransactionalSpr
public MyTransactualControllermyTransactualController;
public MyTransactualController getMyTransactualControll
{
returnthis.myTransactualController;
}
public void setMyTransactualControll
}
4.就象你通常操作“普通的”JUnit测试一样实现测试方法:
public void testCorrectBehavior()throws Exception{ //运行该事务性方法 myTransactualController.submitPayment(new Payment( 100 ) );
assertTrue(myTransactualController.isValid() );}
注意,你是在调用可能会更新数据库的方法submitPayment。Spring的JUnit扩展(AbstractTransactionalSpr
5.如果你需要执行任何安装或清除任务,则可以重载AbstractTransactionalSpr
- Spring Mock--用于Spring 的单元测试
- Spring-Mock--用于Spring 的单元测试
- spring-mock单元测试新方法
- Spring Mock单元测试
- 利用Spring的mock进行单元测试
- 利用spring的mock类进行单元测试
- 利用spring的mock类进行单元测试
- 利用spring的mock类进行单元测试
- 利用Spring的mock对控制层进行单元测试
- Spring MVC的单元测试和集成测试(不使用mock)
- 使用Mock 对spring mvc 的controller层进行单元测试
- Spring MVC的单元测试和集成测试(不使用mock)
- 使用spring-mock进行dao单元测试
- spring-boot整合Mock进行单元测试
- spring MVC mock类单元测试(controller)
- spring test集成resteasy mock单元测试
- Spring学习12-Spring利用mock进行单元测试
- 今天使用了spring-mock来进行单元测试
- 5天不再惧怕多线程——第一天 尝试Thread
- 数据结构基础7.7:基数排序
- Android权限列表permission说明 (一)
- Genero SQL Performance
- time_expire时间过短,刷卡至少1分钟,其他5分钟
- Spring-Mock--用于Spring 的单元测试
- PHP中的SQL优化
- 蓝桥 入门训练 Fibonacci数列
- 北上广不相信眼泪——读工业4.0时代有感
- 黑马程序员——OC学习——基础语法二
- 强制弹出系统键盘(禁用搜狗键盘)
- 倒计时获取验证码 runOnUiThread Timer TimerTask
- Device could not be initialized or no devices found
- [LeetCode]Easy合集I