MockMvc 对 Spring MVC 进行测试

MockMvc 对 Spring MVC 进行测试,第1张

我们将使用 Spring 的 @WebAppConfiguration 注释来测试 web 控制器。@WebAppConfiguration 是一个类级注释,它档橘侍将加载特定于 web 的 ApplicationContext,即 WebApplicationContext 。

@WebAppConfiguration 所伍唤其中的配置中指定的 web application 的目录的默认路径是 src/main/webapp 。<small>当然,你可以用自己指定的值来覆盖这个默认值。</small>

另外, @WebAppConfiguration 必须与 @ContextConfiguration 结合使用。 <small>@ContextConfiguration 则是用于指定 Spring 配置文件或行吵配置类的。</small>

Spring 3.2 之后出现了 org.springframework.test.web.servlet.MockMvc 类,对 Restful 风格的 Spring MVC 单元测试进行支持。

spring 集成测试中 对mock 的集成实在是太棒了!但是使用请注意一下3个条件。

junit 必须使用4.9以上

同时您的框架必须是用spring mvc

spring 3.2以上旁消明才完美支持

目前使用spring MVC 取代struts2 的很多,spring MVC 的各种灵活让人无比销魂!所以使用spring MVC吧!

以前在对接口(主要是java服务端提供的接口(一般是:webService,restful))进行测试的中 一般用以下俩种方法。测试流程如图:

1 直接使用httpClient

 这方法各种运告麻烦

2 使用Spring 提供的RestTemplate

 错误不好跟踪,必须开着服务器

使用mockMVC都桥袭不是问题了看使用实例:

使用事例如下:父类

import org.junit.runner.RunWith

import org.springframework.beans.factory.annotation.Autowired

import org.springframework.test.context.ContextConfiguration

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner

import org.springframework.test.context.web.WebAppConfiguration

import org.springframework.web.context.WebApplicationContext

@WebAppConfiguration

@ContextConfiguration(locations = { "classpath:applicationContext.xml",  

"classpath:xxxx-servlet.xml" })

public class AbstractContextControllerTests {

 @Autowired

 protected WebApplicationContext wac

}

子类:

import org.junit.Before

import org.junit.Test

import org.junit.runner.RunWith

import org.springframework.beans.factory.annotation.Autowired

import org.springframework.http.MediaType

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner

import org.springframework.test.web.servlet.MockMvc

import org.springframework.test.web.servlet.setup.MockMvcBuilders

import com.conlect.oatos.dto.status.RESTurl

import com.qycloud.oatos.server.service.PersonalDiskService

//这个必须使用junit4.9以上才有。

@RunWith(SpringJUnit4ClassRunner.class)

public class PersonalDiskMockTests extends AbstractContextControllerTests {

 

 

 private static String URI = RESTurl.searchPersonalFile

 private MockMvc mockMvc

 

 private String json ="{\"entId\":1234,\"userId\":1235,\"key\":\"new\"}"

 

 @Autowired

 private PersonalDiskService personalDiskService

 @Before

 public void setup() {

     //this.mockMvc = webAppContextSetup(this.wac).alwaysExpect(status().isOk()).build()

     this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService).build()

 }

@Test

 public void readJson() throws Exception {

     this.mockMvc.perform(

             post(URI, "json").characterEncoding("UTF-8")

                 .contentType(MediaType.APPLICATION_JSON)

                 .content(json.getBytes()))

             .andExpect(content().string("Read from JSON: JavaBean {foo=[bar], fruit=[apple]}")

                 )

 }

上面是简单的例子,实际使用起来可以稍做修改。记得导入spring -test jar 包。无需额外配置(是不是很方便!)

当然和junit 的assert 一起用的话效果更好。下面贴点例子。copy就能跑。

Java代码

package com.qycloud.oatos.server.test.mockmvcTest

import static org.junit.Assert.fail

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post

import java.io.UnsupportedEncodingException

import java.lang.reflect.Field

import org.springframework.http.MediaType

import org.springframework.test.web.servlet.MockMvc

import com.conlect.oatos.dto.status.CommConstants

import com.conlect.oatos.dto.status.ErrorType

import com.conlect.oatos.http.PojoMapper

public class MockUtil {

 /**

  * mock

  *

  * @param uri

  * @param json

  * @return

  * @throws UnsupportedEncodingException

  * @throws Exception

  */

 public static String mock(MockMvc mvc, String uri, String json)

         throws UnsupportedEncodingException, Exception {

     return mvc

             .perform(

                     post(uri, "json").characterEncoding("UTF-8")

                             .contentType(MediaType.APPLICATION_JSON)

                             .content(json.getBytes())).andReturn()

             .getResponse().getContentAsString()

 }

 

 /**

  *

  * @param re 返回值

  * @param object 要转换的对象

  * @param testName 当前测试的对象

  */

 public static <T>void check(String re, Class<T>object,String testName) {

     System.out.println(re)

     if (ErrorType.error500.toString().equals(re)) {

         System.out.println("-----该接口测试失败:-----"

                 + testName)

         fail(re)

     } else if (CommConstants.OK_MARK.toString().equals(re)) {

         System.out.println("-----该接口测试成功:-----"

                 + testName)

     }else{

         System.out.println("-----re----- :"+re)

     }

     if (object != null) {

         if (re.contains(":")) {

             try {

                 T t = PojoMapper.fromJsonAsObject(re, object)

                 System.out.println("-----该接口测试成功:-----"

                         + testName)

             } catch (Exception e) {

                 System.out.println("-----该接口测试失败:-----"

                         + testName)

                 fail(e.getMessage())

             }

         }

     }

 }

 /**

  * 初始化版本信息。每次调用测试用力之前首先更新版本信息

  * @param mockMvc

  * @param url

  * @param fileId

  * @param class1

  * @return

  * @throws UnsupportedEncodingException

  * @throws Exception

  */

 public static <T>Long updateVersion(MockMvc mockMvc, String url,

         Long fileId, Class<T>class1) throws UnsupportedEncodingException, Exception {

     

     String re = mock(mockMvc, url, fileId+"")

     

     T dto = PojoMapper.fromJsonAsObject(re, class1)

     

Long version = Long.parseLong(dto.getClass().getMethod("getVersion").invoke(dto).toString()) 

     System.out.println("version = "+version)

     

     return version

     

 }

 

}

使用如下:

Java代码

@RunWith(SpringJUnit4ClassRunner.class)

public class PersonalDiskMockTests extends AbstractContextControllerTests {

 private MockMvc mockMvc

 private static Long entId = 1234L

 private static Long adminId = 1235L

 @Autowired

 private PersonalDiskService personalDiskService

 @Before

 public void setup() {

     this.mockMvc = MockMvcBuilders.standaloneSetup(personalDiskService)

             .build()

 }

 /***

  * pass

  * 全局搜索企业文件

  *

  * @throws Exception

  */

 @Test

 public void searchPersonalFile() throws Exception {

     SearchFileParamDTO sf = new SearchFileParamDTO()

     sf.setEntId(entId)

     sf.setKey("li")

     sf.setUserId(adminId)

     String json = PojoMapper.toJson(sf)

     String re = MockUtil.mock(this.mockMvc, RESTurl.searchPersonalFile,

             json)

     MockUtil.check(re, SearchPersonalFilesDTO.class, "searchPersonalFile")

 }

当然@setup里面是每个@test执行时都会执行一次的,所以有些需要每次都实例化的参数可以放进来

如下:

Java代码

@Autowired

 private ShareDiskService shareDiskService

 @Before

 public void setup() {

     this.mockMvc = MockMvcBuilders.standaloneSetup(shareDiskService)

             .build()

     try {

         initDatas()

     } catch (Exception e) {

         e.printStackTrace()

     }

 }

 

 private void initDatas() throws UnsupportedEncodingException, Exception {

     FileIdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,FileId,ShareFileDTO.class)

     File2IdVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFileById,File2Id,ShareFileDTO.class)

     oldPicFolderVersion = MockUtil.updateVersion(mockMvc,RESTurl.getShareFolderById,oldPicFolderId,ShareFolderDTO.class)

 }

ok!基本使用大致如此,代码没有些注释,但是很简单,看懂是没问题的。权当抛砖引玉。希望大家加以指正!

SpringMVC单元测试的独立测试;对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等,所以为了可以对Controller进行测试,我们引入MockMVC。

MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统蚂亩一而且很方便。

★ 服务器端SpringMVC测试的主入口点。

★ 通过MockMVCBuilders建造者的静态方法去建造MockMVCBuilder,MockMvc由MockMVCBuilder构造。

★ 核心方法:perform(RequestBuilder rb),执行一个RequestBuilder请,会自动执行SpringMVC的流程并映射到相应的控制器执行处理,该方法的返回值是一个ResultActions

★ MockMVCBuilder是使用构造者模式来构造MockMvc的构造弯雀器。

★ 主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder。

★ 可以直接使用静态工厂MockMvcBuilders创建即可,不需要直接使用上面两个实现类。

★ 负责创建MockMVCBuilder对象。

两种创建方式

★ 用来构建Request请求的,其主要有两个子类。

★ MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(闷闹森如文件上传使用),即用来Mock客户端请求需要的所有数据。

★ MockMvc.perform后将得到ResultActions

★ andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确。

★ andDo:添加ResultHandler结果处理器,如调试时打印结果到控制台。

★ andReturn:最后返回相应的MvcResult;然后进行自定义验证或下一步的异步处理。

★ MockMvcResultMatchers

用来匹配执行完请求后的**结果验证。

果匹配失败将抛出相应的异常。

包含了很多验证API方法。

★ MockMvcResultHandlers 结果处理器,表示要对结果做处理的需要用到。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12171407.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存