`
simgsg
  • 浏览: 91331 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

利用spring的mock类进行单元测试

 
阅读更多
<p>利用spring的mock类进行单元测试: <br>spring框架提供了大量测试的mock类,包括与jndi,porlet,web应用相关的mock类。尤其是web应用相关的mock类,可以大大提高web组件测试的方便性。</p>
<p>打开spring的下载包的mock文件夹(路径...mock/org/springframework/mock/web),就发觉有如下几个文件:</p>
<p><span style="color: #ff0000;">MockHttpServletRequest</span>:是HttpServletRequest接口的mock实现,用来模拟客户端的HTTP请求,很常用的一个类。</p>
<p><span style="color: #ff0000;">MockHttpServletResponse</span>:是HttpServletResponse接口的mock实现,用于模拟服务器对客户端的响应。</p>
<p><span style="color: #ff0000;">MockHttpSession</span>:是对HttpSession接口的mock实现。</p>
<p><span style="color: #ff0000;">DelegatingServletInputStream</span>:是对ServletInputStream接口的mock实现。</p>
<p><span style="color: #ff0000;">DelegatingServletOutputStream</span>:ServletOutputStream的mock实现。需要拦截和分析服务器的输出的流的内容,可以使用该类。</p>
<p>其他的,例如MockFilterConfig,MockPageContext(可以测试预编译的JSP),MockRequestDispatcher,MockServletConfig看名称就知道大概是mock什么的。 <br>举一个例子: <br> MockHttpServletRequest request = new MockHttpServletRequest("POST","/index.do"); <br> request.addParameter("username","name"); <br> request.addParameter("password","word"); </p>
<p><span style="color: #0000ff;"><strong>利用spring来进行集成测试</strong></span>: <br>1、<span style="color: #ff0000;">AbstractSpringContextTests类</span><span style="color: #ff0000;">[1],</span>该类全部方法是protected的,<span style="color: #0000ff;">通常不使用这个类,而使用它的子类们</span>。</p>
<p>2、<span style="color: #ff0000;">AbstractDependencyInjectionSpringContextTests类</span>[2]:<span style="color: #ff0000;">继承于类[1]</span>:名字N长的。如果<span style="color: #0000ff;">仅仅使用Spring依赖注入功能</span>,<span style="color: #0000ff;">可以让测试用例继承该类</span>。</p>
<p>3、<span style="color: #ff0000;">AbstractTransactionalSpringContextTests类[3]:继承于类[2]</span>,继承该类的测试用例在<span style="color: #0000ff;">spring管理的事务中进行,测试完后对数据库的记录不会造成任何影响</span>。<span style="color: #ff00ff;">你对数据库进行一些操作后,它会自动把数据库回滚,这样就保证了你的测试对于环境没有任何影响</span></p>
<p>4、<span style="color: #ff0000;">AbstractTransactionalDataSourceSpringContextTests</span>:<span style="color: #ff0000;">继承于类[3]</span>,功能更强大,<span style="color: #0000ff;">用于测试持久层组件,</span>看其源代码,有一行"protected JdbcTemplate jdbcTemplate;",<span style="color: #0000ff;">提供了一个JdbcTemplate的变量</span>,通过该对象可以直接操作数据库。</p>
<p><a href="http://lighter.javaeye.com/blog/41733">http://lighter.javaeye.com/blog/41733</a>还提供了两个用spring来进行集成测试(对数据库操作进行测试),业务测试(对业务层进行测试)的例子供下载。</p>
<p><span style="font-size: small; color: #ff0000;"><strong>***如何在你的TestCase Class里取得spring context (注意路径问题)?***</strong></span></p>
<p>你的TestCase Class必须继承的是上述四个<span style="color: #ff0000;">AbstractXXXSpringContextTests</span>中的其中一个,那么就<span style="color: #0000ff;">必须实现下面这个方法来取得spring context</span>:</p>
<p> protected abstract String[] <span style="color: #ff0000;">getConfigLocations</span>();</p>
<p>例如:</p>
<p><span style="color: #ff0000;">public String[] getConfigLocations() {<br> String[] configLocations = { "applicationContext.xml","hibernate-context.xml" };<br> return configLocations;<br>}</span></p>
<p><br><span style="font-size: medium; color: #ff00ff;"><strong>请 注意要加载的context xml file的路径问题:上述的代码是基于classpath,因此applicationContext.xml和hibernate- context.xml必须放在classpath里(方法一是把xml files放到WEB-INF/classes目录下,另一种方法就是在project properties里把xml files的路径加到classpath里)</strong></span></p>
<p>那么<span style="font-size: small; color: #ff00ff;"><strong>如果你一定要把context xml files放到WEB-INF目录下,也是可以的,那么应该基于file(基于file的相对路径是相对于project root folder),代码如下:</strong></span></p>
<p><span style="color: #000000;">public String[] getConfigLocations() {<br> String[] configLocations = { "<span style="color: #ff0000;">file:WebContent/WEB-INF/applicationContext.xml</span>"};<br> return configLocations;<br>}<br></span></p>
<p><span style="color: #ff0000;">AbstractXXXSpringContextTests</span>就会根据根据<span style="color: #ff0000;">getConfigLocations</span>方法返回的context xml位置的数组来加载<span style="color: #ff0000;">并且对加载的Context提供缓存</span>。 这是非常重要的,因为如果你在从事一个大项目时,启动时间可能成为一个问题--这不是Spring自身的开销,而是被Spring容器实例化的对象在实例 化自身时所需要的时间。例如,一个包括50-100个Hibernate映射文件的项目可能需要10-20秒的时间来加载上述的映射文件,如果在运行每个 测试fixture里的每个测试案例前都有这样的开销,将导致整个测试工作的延时,最终有可能(实际上很可能)降低效率。</p>
<p>在某种极偶然的情况下,某个测试可能“弄脏”了配置场所,并要求重新加载--例如改变一个bean的定义或者一个应用对象的状态--你可以调用 <code class="classname"><span style="color: #ff0000;">AbstractDependencyInjectionSpringContextTests</span></code> 上的 <code class="literal"><span style="color: #ff0000;">setDirty</span>()</code> 方法来重新加载配置并在执行下一个测试案例前重建application context</p>
<p></p>
<p>当类 <span style="color: #ff0000;">AbstractDependencyInjectionSpringContextTests</span><span style="color: #ff0000;">(及其子类)</span>装载你的Application Context时,你<span style="color: #0000ff;">可以通过Setter方法来注入</span>你想要的来自context的bean,而<span style="color: #0000ff;">不需要显式的调用applicationContext.getBean(XXX)</span>。因为AbstractDependencyInjectionSpringContextTests会从getConfigLocations()方法指定的配置文件中帮你自动注入</p>
<p>下面的例子就是通过setter方法来获得context里的ProductManager bean:</p>
<p>public class MyTest <span style="color: #ff0000;">extends AbstractDependencyInjectionSpringContextTests</span> {<br> ProductManager productManager;</p>
<p> public String[] <span style="color: #ff0000;">getConfigLocations</span>() {<br> String[] configLocations = { "file:WebContent/WEB-INF/applicationContext.xml" };<br> return configLocations;<br> }</p>
<p> public void testGetProduct() {<br> assertEquals("tomson",productManager.getProductByName("tomson").getName());<br> }<br></p>
<p><span style="color: #0000ff;"> //通过setter方法自动从context里注入productManager bean,而不用显示调用applicationContext</span><span style="color: #0000ff;">.getBean(XXX)</span><br> public void <span style="color: #ff0000;">setProductManager</span>(ProductManager productManager) {<br> this.productManager = productManager;<br> }<br>}</p>
<p>但是<span style="color: #ff0000;"><strong>如 果context里有多个bean都定义为一个类型(例如有多个bean都是ProductManager class类型的),那么对这些bean就无法通过setter方法来自动依赖注入(因为有多个bean同一个类型,不知要自动注入哪个)。在这种情况下 你需要显示的调用applicationContext.getBean(XXX)来注入</strong></span>。如:</p>
<p>public class MyTest extends AbstractDependencyInjectionSpringContextTests {<br> ProductManager productManager;</p>
<p> public String[] getConfigLocations() {<br> String[] configLocations = { "file:WebContent/WEB-INF/applicationContext.xml" };<br> return configLocations;<br> }</p>
<p>public void onSetUp() {<br><span style="color: #ff0000;"> productManager = (ProductManager) applicationContext.getBean("productManager");</span><br> }</p>
<p> public void testGetProduct() {<br> assertEquals("tomson",productManager.getProductByName("tomson").getName());<br> }<br><br>}</p>
<p>如果你的<span style="color: #ff0000;">TestCase不使用依赖注入,只要不定义任何setters方法即可</span>。<span style="color: #ff0000;">或者你可以继承 AbstractSpringContextTests</span> --这个 org.springframework.test 包中的根类,而不是继承<span style="color: #ff0000;">AbstractDependencyInjectionSpringContextTests(及其子类)</span>。这是<span style="color: #0000ff;">因为AbstractSpringContextTests 只包括用来加载Spring Context的便利方法但没有自动依赖注入的功能</span></p>
分享到:
评论

相关推荐

    java单元测试 spring mock的使用

    在java web应用中,通过mock技术可以模拟spring容器,从而进行单元测试,详细可以参见本文

    spring-mock.jar

    Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi....

    单元测试高级特性-mock模拟网络请求

    单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络请求单元测试高级特性--mock模拟网络...

    JMOCKIT mock 静态方法 单元测试

    可以用来Mock JAVA代码中的静态方法

    使用PythonMock类进行单元测试

    但mock在单元测试中扮演一个什么角色呢?有时,你需要为单元测试的初始设置准备一些“其他”的代码资源。但这些资源兴许会不可用,不稳定,或者是使用起来太笨重。你可以试着找一些其他的资源替代;或者你可以通过...

    Java单元测试增强工具源码,换种思路写Mock,让单元测试更简单

    Java单元测试增强工具源码,换种思路写Mock,让单元测试更简单 构建项目 主项目使用JDK 1.6+和Maven 3+版本构建,其中demo子项目需要JDK 1.8+版本。 mvn clean install 本地生成文档 docsify serve docs ...

    mock-all-things:使用 mock 进行 python 单元测试的示例

    模拟一切使用 mock 进行 python 单元测试的示例模拟 python 2.7: : (这里也有很多很好的例子) 从图书馆的主页: “mock 是一个用于在 Python 中进行测试的库。它允许您用模拟对象替换被测系统的某些部分,并对...

    有效使用Mock编写java单元测试

    Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构。然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编写出...

    使用Gomock进行单元测试的方法示例

    主要介绍了使用Gomock进行单元测试的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    spring-mock-2.0-rc3.jar

    Spring针对J2EE的常用Web接口提供了Mock,这些组件被发布于spring-mock.jar,介绍如下: MockHttpServletRequest:HttpServletRequest接口的mock实现。 MockHttpServletResponse:HttpServletResponse接口的mock...

    struts-junit spring-mock spring-test junit的javadoc.jar文档

    struts-junit spring-mock spring-test junit等的javadoc.jar格式的API文档,直接导入Eclipse/MyEclipse/Netbeans等IDE即可实现快速API查询。 包含以下文件: File name -------------------------------------- ...

    unitils整合dbunit利用excel进行单元测试

    unitils整合dbunit利用excel进行单元测试 包含mock以及整合spring进行测试

    spring-mock-2.0.8.jar

    spring-mock-2.0.8.jar

    mockito单元测试使用

    单元测试就是模块测试,我的理解一个模块就是一个类,主要是指我们的 Service 模块,因为一个项目中大部分的业务逻辑都在 Service 层。我们专注测试 Service 中的方法即可。集成测试也就是多个模块的联合测试,...

    基于模拟对象MockObject的单元测试研究.pdf

    不错的文档,提供给科研人员

Global site tag (gtag.js) - Google Analytics