基于mock对象的Spring Web组件单元测试Word下载.docx
《基于mock对象的Spring Web组件单元测试Word下载.docx》由会员分享,可在线阅读,更多相关《基于mock对象的Spring Web组件单元测试Word下载.docx(16页珍藏版)》请在冰豆网上搜索。
●DelegatingServletInputStream:
这个对象用于ServletInputStream接口的mock实现。
●DelegatingServletOutputStream:
这个对象将代理ServletOutputStream实现。
在需要拦截和分析写向一个输出流的内容时,我们可以使用它。
总之,在实现你自己的测试控制器时,上面这些对象是最为有用的。
然而,Spring也提供了下列相应于其它不太常用的组件的mock实现(如果我们是一个底层API开发者,那么我们可能会找到其各自的相应用法)。
3、Spring中的其它的Mock技术的API
(1)MockFilterConfig
这是FilterConfig接口的一个mock实现。
(2)MockPageContext
这是JSPPageContext接口的一个mock实现。
你会发现这个对象的使用有利于测试预编译的JSP。
(3)MockRequestDispatcher
RequestDispatcher接口的一个mock实现,你主要在其它mock对象内使用它。
(4)MockServletConfig
这是ServletConfig接口的一个mock实现。
在单元测试某种Web组件(例如Struts框架所提供的Web组件)时,要求你设置由MockServletContext所实现的ServletConfig和ServletContext接口。
4、如何使用这些mock对象
(1)MockHttpServletRequest类
HttpServletRequest是一个持有描述HTTP参数的固定值的组件,而正是这些参数驱动Web组件的功能。
MockHttpServletRequest,作为HttpServletRequest接口的一个实现,允许我们设置这些不可改变的参数。
在典型的Web组件测试情形下,我们可以实例化这个对象并按如下方式设置其中的任何参数。
(2)指定表单方法和表单行为
MockHttpServletRequestrequest=newMockHttpServletRequest("
GET"
"
/SpringWeb/hello.do"
);
request.addParameter("
nameOne"
valueOne);
nameTwo"
valuetwo);
注意:
对上面的MockHttpServletRequestrequest=newMockHttpServletRequest("
也可以改变为下面的代码:
MockHttpServletRequestrequest=newMockHttpServletRequest();
request.setMethod("
request.setRequestURI("
同样地,我们可以实例化并全面地控制和分析HttpServletResponse和HttpSession对象。
5、Spring对JUnit框架的扩展
(1)AbstractDependencyInjectionSpringContextTests
这是一个针对所有测试的超类,其具体使用依赖于Spring上下文。
(2)AbstractSpringContextTests
这是一个针对所有的JUnit测试情形的超类。
它使用一个Spring上下文。
并且,一般在测试中不是直接使用它,而是使用AbstractDependencyInjectionSpringContextTests或者AbstractTransactionalSpringContextTests这样的派生类。
(3)AbstractTransactionalSpringContextTests
这是一个针对所有测试的超类,我们一般把它应用在事务相关的测试中。
注意,一旦完成每个测试它就会正常地回滚事务;
而且你需要重载onSetUpInTransaction和onTearDownInTransaction方法以便手工开始并提交事务。
(4)AbstractTransactionalDataSourceSpringContextTests
这是AbstractTransactionalSpringContextTests的一个子类,它使用了Spring的基于JDBC的jdbcTemplate工具类。
所有上面这些扩展将极大程度地简化在测试时对于相关操作的依赖性注入和事务管理。
6、测试能够转发到一个正确的视图
基于输入参数生成正确的视图可能是在操作一个Web应用程序时最普通的功能。
在SpringMVC的上下文中,这意味着SpringMVC将基于参数的状态返回某种ModelAndView对象。
我们可以通过简单地利用如下的Mock对象以一个常规JUnit测试方式来测试这项功能:
publicvoidfinaltestGettingToDetails()throwsException
{
MyControllermyController=newMyController();
myController.setDetailsView(detailsViewName);
MockHttpServletRequestrequest=newMockHttpServletRequest();
MockHttpServletResponseresponse=newMockHttpServletResponse();
request.setMethod("
POST"
request.addParameter("
viewDetails"
true"
ModelAndViewmodelAndView=myController.handleRequest(request,response);
assertEquals("
Incorrectviewname"
detailsViewName,modelAndView.getViewName());
}
既然控制器很可能会利用一些服务对象来决定结果视图,那么你还可以定制控制器中所用的这些mock服务对象。
7、会话相关的操作
对于任何J2EEWeb应用程序来说,另一个必须实现的操作是HttpSession绑定处理。
例如,SpringMVC可能需要决定是否一个对象处于会话中及其具体状态以便产生正确的结果。
我们可以利用MockHttpSession对象和JUnit框架测试这种情形。
请参考如下的代码片断:
publicvoidtestInvokesCorrectMethodWithSession()throwsException
TestControllercont=newTestController();
/invoiceView.app"
request.setSession(newMockHttpSession(null));
HttpServletResponseresponse=newMockHttpServletResponse();
ModelAndViewmv=cont.handleRequest(request,response);
assertTrue("
InvokedloggedInmethod"
cont.wasInvoked("
loggedIn"
));
viewnameis"
mv.getViewName().equals("
Onlyonemethodinvoked"
cont.getInvokedMethods()==1);
//测试控制器但是不使用会话
request=newMockHttpServletRequest("
response=newMockHttpServletResponse();
try
cont.handleRequest(request,response);
fail("
Shouldhaverejectedrequestwithoutsession"
catch(ServletExceptionex)
//在此加入期盼的异常处理
二、基于mock对象的SpringWeb组件单元测试技术的实现示例
1、打开我们的被测试的Project----“在JBUilder中创建Spring的MVCWeb应用.doc”一文中的示例
(1)打开它
(2)执行它以看是否有语法错误
2、在JBuilder中再新建一个测试项目-----采用分离的方法
(1)名称为TestSpringWebApp
(2)将被测试的类(SpringappController.java)引入到本测试项目中
3、为本测试Project增加Spring中对Mock的支持的*.jar包文件----spring-mock.jar
(1)由于Spring的Mock技术需要spring-mock.jar的支持,因此我们应该将它添加到我们的Project中。
(2)将spring-mock.jar增加到本Project的库SpringJar中。
(3)再将SpringJar引入到我们的Project中,另外还需要将被测试的项目引入到我们的测试项目中。
再编译本Project以观察是否还出现错误----此时,不应该再出现找不到XXX类的错误!
4、在该Project中增加一个TestCase类
选择我们的被测试的方法handleRequest方法
设置类名称为TestSpringappController,包名称为springwebapptest,基类为junit.framework.TestCase
由于本例不需要其它的固件,因此不需要添加。
最后点击“Finish”按钮,Jbuilder将产生下面的代码。
packagespringwebapptest;
importjunit.framework.*;
importspringwebapp.*;
importjavax.servlet.*;
importjava.io.*;
importjavax.servlet.http.*;
importorg.springframework.web.servlet.*;
publicclassTestSpringappControllerextendsTestCase
privateSpringappControllerspringappController=null;
protectedvoidsetUp()throwsException{
super.setUp();
springappController=newSpringappController();
//不能再采用该方式来产生对象!
}
protectedvoidtearDown()throwsException{
springappController=null;
super.tearDown();
publicvoidtestHandleRequest()throwsServletException,IOException{
HttpServletRequestrequest=null;
HttpServletResponseresponse=null;
ModelAndViewexpectedReturn=null;
ModelAndViewactualReturn=springappController.handleRequest(request,response);
returnvalue"
expectedReturn,actualReturn);
/**@todofillinthetestcode*/
5、编程修改前面的代码
importorg.springframework.mock.web.*;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.FileSystemXmlApplicationContext;
protectedvoidsetUp()throwsException
{
StringspringXMLFilePath="
C:
/temp/SpringWebApp/SpringWeb/WEB-INF/springapp-servlet.xml"
;
ApplicationContextapplicationContext=newFileSystemXmlApplicationContext(springXMLFilePath);
springappController=(SpringappController)applicationContext.getBean("
springappController"
protectedvoidtearDown()throwsException
publicvoidtestHandleRequest()throwsServletException,IOException
//request.addParameter("
paraName"
paraValue);
//如果在请求过程中需要参数,可以利用该方法提供
/*目前不需要下面的代码,因为我们直接对handleRequest方法调用
*/
StringexpectedTargetPage=springappController.getViewPage();
//获得期望跳转的目标
ModelAndViewmodelAndView=springappController.handleRequest(request,response);
StringactualTargetPage=modelAndView.getViewName();
//获得实际跳转的目标
assertEquals(expectedTargetPage,actualTargetPage);
6、执行前面的TestCase类-------不需要启动服务器
将产生下面的提示结果
同时可以观察输出的状态结果
学员练习:
实现对本Web项目中的业务组件类TimeDateBusiness进行测试。
注意的问题:
应该选择什么类型的测试方法?
!
1、将被测试的类TimeDateBusiness引入到测试项目中
2、针对上面的TimeDateBusiness类产生出对应的TestCase类
将产生出下面的状态
3、编程该TestCase类
publicclassTestTimeDateBusinessextendsTestCase
privateSpringWebAppBusinesstimeDateBusiness=null;
//timeDateBusiness=newTimeDateBusiness();
StringspringXMLFilePath="
D:
/JUnitExmp/SpringWebApp/SpringWeb/WEB-INF/springapp-servlet.xml"
timeDateBusiness=(SpringWebAppBusiness)applicationContext.getBean("
timeDateBusiness"
timeDateBusiness=null;
publicvoidtestDoGetTimeBusiness()
StringactualReturn=timeDateBusiness.doGetTimeBusiness();
this.assertNotNull(actualReturn);
4、执行本测试用例
将出现下面的结果
5、再通过一个测试套件来运行我们的测试用例