SpringMVC 测试 mockMVC

 

SpringMVC测试框架

基于RESTful风格的SpringMVC的测试,我们可以测试完整的Spring MVC流程,即从URL请求到控制器处理,再到视图渲染都可以测试。

一 MockMvcBuilder

MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分别对应两种测试方式,即独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。对于我们来说直接使用静态工厂MockMvcBuilders创建即可。

1.集成Web环境方式

MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc;

复制代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:config/IncotermsRestServiceTest-context.xml")
@WebAppConfiguration
public class IncotermsRestServiceTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic void setup() {this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();   //构造MockMvc}...
}
复制代码

注意:
(1)@WebAppConfiguration:测试环境使用,用来表示测试环境使用的ApplicationContext将是WebApplicationContext类型的;value指定web应用的根;
(2)通过@Autowired WebApplicationContext wac:注入web环境的ApplicationContext容器;
(3)然后通过MockMvcBuilders.webAppContextSetup(wac).build()创建一个MockMvc进行测试;

2.独立测试方式

MockMvcBuilders.standaloneSetup(Object... controllers):通过参数指定一组控制器,这样就不需要从上下文获取了;

复制代码
public class PricingExportResultsRestServiceTest {@InjectMocksprivate PricingExportResultsRestService pricingExportResultsRestService;@Mockprivate ExportRateScheduleService exportRateScheduleService;@Mockprivate PricingUrlProvider pricingUrlProvider;private MockMvc mockMvc;@Beforepublic void setup() {MockitoAnnotations.initMocks(this);mockMvc = MockMvcBuilders.standaloneSetup(pricingExportResultsRestService).build();  //构造MockMvc}...
}
复制代码

主要是两个步骤:
(1)首先自己创建相应的控制器,注入相应的依赖
(2)通过MockMvcBuilders.standaloneSetup模拟一个Mvc测试环境,通过build得到一个MockMvc

 

二 MockMvc

先看一个测试例子1:

复制代码
  @Testpublic void createIncotermSuccess() throws Exception {IncotermTo createdIncoterm = new IncotermTo();createdIncoterm.setId(new IncotermId(UUID.fromString("6305ff33-295e-11e5-ae37-54ee7534021a")));createdIncoterm.setCode("EXW");createdIncoterm.setDescription("code exw");createdIncoterm.setLocationQualifier(LocationQualifier.DEPARTURE);when(inventoryService.create(any(IncotermTo.class))).thenReturn(createdIncoterm);mockMvc.perform(post("/secured/resources/incoterms/create").accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON).content("{\"code\" : \"EXW\", \"description\" : \"code exw\", \"locationQualifier\" : \"DEPARTURE\"}".getBytes()))//.andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("id.value").exists()).andExpect(jsonPath("id.value").value("6305ff33-295e-11e5-ae37-54ee7534021a")).andExpect(jsonPath("code").value("EXW"));}
复制代码

perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台;
andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理;

 

看一个具体的例子2:

复制代码
    @Test  public void testView() throws Exception {  MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/user/1"))  .andExpect(MockMvcResultMatchers.view().name("user/view"))  .andExpect(MockMvcResultMatchers.model().attributeExists("user"))  .andDo(MockMvcResultHandlers.print())  .andReturn();  Assert.assertNotNull(result.getModelAndView().getModel().get("user"));  }  
复制代码

整个过程:
1、mockMvc.perform执行一个请求;
2、MockMvcRequestBuilders.get("/user/1")构造一个请求
3、ResultActions.andExpect添加执行完成后的断言
4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
5、ResultActions.andReturn表示执行完成后返回相应的结果。

整个测试过程非常有规律:
1、准备测试环境
2、通过MockMvc执行请求
3.1、添加验证断言
3.2、添加结果处理器
3.3、得到MvcResult进行自定义断言/进行下一步的异步请求
4、卸载测试环境

 

三 RequestBuilder/MockMvcRequestBuilders

从名字可以看出,RequestBuilder用来构建请求的,其提供了一个方法buildRequest(ServletContext servletContext)用于构建MockHttpServletRequest;其主要有两个子类MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(如文件上传使用),即用来Mock客户端请求需要的所有数据。

1.MockMvcRequestBuilders主要API

MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根据uri模板和uri变量值得到一个GET请求方式的MockHttpServletRequestBuilder;如get(/user/{id}, 1L);
MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables):同get类似,但是是POST方法;
MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables):同get类似,但是是PUT方法;
MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) :同get类似,但是是DELETE方法;
MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables):同get类似,但是是OPTIONS方法;
MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object... urlVariables): 提供自己的Http请求方法及uri模板和uri变量,如上API都是委托给这个API;
MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables):提供文件上传方式的请求,得到MockMultipartHttpServletRequestBuilder;
RequestBuilder asyncDispatch(final MvcResult mvcResult):创建一个从启动异步处理的请求的MvcResult进行异步分派的RequestBuilder;

2.MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder API

(1)MockHttpServletRequestBuilder API

MockHttpServletRequestBuilder header(String name, Object... values)/MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders):添加头信息;
MockHttpServletRequestBuilder contentType(MediaType mediaType):指定请求的contentType头信息;
MockHttpServletRequestBuilder accept(MediaType... mediaTypes)/MockHttpServletRequestBuilder accept(String... mediaTypes):指定请求的Accept头信息;
MockHttpServletRequestBuilder content(byte[] content)/MockHttpServletRequestBuilder content(String content):指定请求Body体内容;
MockHttpServletRequestBuilder cookie(Cookie... cookies):指定请求的Cookie;
MockHttpServletRequestBuilder locale(Locale locale):指定请求的Locale;
MockHttpServletRequestBuilder characterEncoding(String encoding):指定请求字符编码;
MockHttpServletRequestBuilder requestAttr(String name, Object value) :设置请求属性数据;
MockHttpServletRequestBuilder sessionAttr(String name, Object value)/MockHttpServletRequestBuilder sessionAttrs(Map<string, object=""> sessionAttributes):设置请求session属性数据;
MockHttpServletRequestBuilder flashAttr(String name, Object value)/MockHttpServletRequestBuilder flashAttrs(Map<string, object=""> flashAttributes):指定请求的flash信息,比如重定向后的属性信息;
MockHttpServletRequestBuilder session(MockHttpSession session) :指定请求的Session;
MockHttpServletRequestBuilder principal(Principal principal) :指定请求的Principal;
MockHttpServletRequestBuilder contextPath(String contextPath) :指定请求的上下文路径,必须以“/”开头,且不能以“/”结尾;
MockHttpServletRequestBuilder pathInfo(String pathInfo) :请求的路径信息,必须以“/”开头;
MockHttpServletRequestBuilder secure(boolean secure):请求是否使用安全通道;
MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor):请求的后处理器,用于自定义一些请求处理的扩展点;

(2)MockMultipartHttpServletRequestBuilder继承自MockHttpServletRequestBuilder,又提供了如下API

MockMultipartHttpServletRequestBuilder file(String name, byte[] content)/MockMultipartHttpServletRequestBuilder file(MockMultipartFile file):指定要上传的文件;

 

四 ResultActions

调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,通过ResultActions完成如下三件事:
ResultActions andExpect(ResultMatcher matcher) :添加验证断言来判断执行请求后的结果是否是预期的;
ResultActions andDo(ResultHandler handler) :添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;
MvcResult andReturn() :返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;

 

五 ResultMatcher/MockMvcResultMatchers

1.ResultMatcher用来匹配执行完请求后的结果验证,其就一个match(MvcResult result)断言方法,如果匹配失败将抛出相应的异常;spring mvc测试框架提供了很多***ResultMatchers来满足测试需求。注意这些***ResultMatchers并不是ResultMatcher的子类,而是返回ResultMatcher实例的。Spring mvc测试框架为了测试方便提供了MockMvcResultMatchers静态工厂方法方便操作;

2.具体的API如下:
HandlerResultMatchers handler():请求的Handler验证器,比如验证处理器类型/方法名;此处的Handler其实就是处理请求的控制器;
RequestResultMatchers request():得到RequestResultMatchers验证器;
ModelResultMatchers model():得到模型验证器;
ViewResultMatchers view():得到视图验证器;
FlashAttributeResultMatchers flash():得到Flash属性验证;
StatusResultMatchers status():得到响应状态验证器;
HeaderResultMatchers header():得到响应Header验证器;
CookieResultMatchers cookie():得到响应Cookie验证器;
ContentResultMatchers content():得到响应内容验证器;
JsonPathResultMatchers jsonPath(String expression, Object ... args)/ResultMatcher jsonPath(String expression, Matcher matcher):得到Json表达式验证器;
XpathResultMatchers xpath(String expression, Object... args)/XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args):得到Xpath表达式验证器;
ResultMatcher forwardedUrl(final String expectedUrl):验证处理完请求后转发的url(绝对匹配);
ResultMatcher forwardedUrlPattern(final String urlPattern):验证处理完请求后转发的url(Ant风格模式匹配,@since spring4);
ResultMatcher redirectedUrl(final String expectedUrl):验证处理完请求后重定向的url(绝对匹配);
ResultMatcher redirectedUrlPattern(final String expectedUrl):验证处理完请求后重定向的url(Ant风格模式匹配,@since spring4);

 

六 一些常用的测试

1.测试普通控制器

mockMvc.perform(get("/user/{id}", 1)) //执行请求  .andExpect(model().attributeExists("user")) //验证存储模型数据  .andExpect(view().name("user/view")) //验证viewName  .andExpect(forwardedUrl("/WEB-INF/jsp/user/view.jsp"))//验证视图渲染时forward到的jsp  .andExpect(status().isOk())//验证状态码  .andDo(print()); //输出MvcResult到控制台

 

2.得到MvcResult自定义验证

MvcResult result = mockMvc.perform(get("/user/{id}", 1))//执行请求  .andReturn(); //返回MvcResult  
Assert.assertNotNull(result.getModelAndView().getModel().get("user")); //自定义断言   

 

3.验证请求参数绑定到模型数据及Flash属性

mockMvc.perform(post("/user").param("name", "zhang")) //执行传递参数的POST请求(也可以post("/user?name=zhang"))  .andExpect(handler().handlerType(UserController.class)) //验证执行的控制器类型  .andExpect(handler().methodName("create")) //验证执行的控制器方法名  .andExpect(model().hasNoErrors()) //验证页面没有错误  .andExpect(flash().attributeExists("success")) //验证存在flash属性  .andExpect(view().name("redirect:/user")); //验证视图  

 

4.文件上传

byte[] bytes = new byte[] {1, 2};  
mockMvc.perform(fileUpload("/user/{id}/icon", 1L).file("icon", bytes)) //执行文件上传  .andExpect(model().attribute("icon", bytes)) //验证属性相等性  .andExpect(view().name("success")); //验证视图  

 

5.JSON请求/响应验证

复制代码
String requestBody = "{\"id\":1, \"name\":\"zhang\"}";  mockMvc.perform(post("/user")  .contentType(MediaType.APPLICATION_JSON).content(requestBody)  .accept(MediaType.APPLICATION_JSON)) //执行请求  .andExpect(content().contentType(MediaType.APPLICATION_JSON)) //验证响应contentType  .andExpect(jsonPath("$.id").value(1)); //使用Json path验证JSON 请参考http://goessner.net/articles/JsonPath/  String errorBody = "{id:1, name:zhang}";  MvcResult result = mockMvc.perform(post("/user")  .contentType(MediaType.APPLICATION_JSON).content(errorBody)  .accept(MediaType.APPLICATION_JSON)) //执行请求  .andExpect(status().isBadRequest()) //400错误请求  .andReturn();  Assert.assertTrue(HttpMessageNotReadableException.class.isAssignableFrom(result.getResolvedException().getClass()));//错误的请求内容体
复制代码

 

6.异步测试

复制代码
  //Callable  MvcResult result = mockMvc.perform(get("/user/async1?id=1&name=zhang")) //执行请求  .andExpect(request().asyncStarted())  .andExpect(request().asyncResult(CoreMatchers.instanceOf(User.class))) //默认会等10秒超时  .andReturn();  mockMvc.perform(asyncDispatch(result))  .andExpect(status().isOk())  .andExpect(content().contentType(MediaType.APPLICATION_JSON))  .andExpect(jsonPath("$.id").value(1));  
复制代码

 

7.全局配置

复制代码
mockMvc = webAppContextSetup(wac)  .defaultRequest(get("/user/1").requestAttr("default", true)) //默认请求 如果其是Mergeable类型的,会自动合并的哦mockMvc.perform中的RequestBuilder  .alwaysDo(print())  //默认每次执行请求后都做的动作  .alwaysExpect(request().attribute("default", true)) //默认每次执行后进行验证的断言  .build();  mockMvc.perform(get("/user/1"))  .andExpect(model().attributeExists("user"));  
复制代码

 

转载于:https://www.cnblogs.com/williamjie/p/9145165.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自顶向下和自底向上测试的优缺点

自顶向下测试方法的主要优点是不需要测试驱动程序&#xff0c;能够在测试阶段的早期实现并验证系统的主要功能&#xff0c;而且能在早期发现上层模块的接口错误。 自顶向下测试方法的主要缺点是需要存根程序&#xff0c;可能遇到与此相联系的测试困难&#xff0c;低层关键模块中…

C++ class中的静态(static)成员

C class中的静态(static)成员 &#xff08;1&#xff09; 静态数据成员 ①一般地静态数据成员在该类定义之外被初始化&#xff0c;如同一个成员函数被定义在类定义之外一样。在这种定义中的静态成员的名字必须被其类名限定修饰&#xff0c;例如下面是_interestRate的初始…

用计算机弹可惜不是你,可惜不是你 还是幸亏不是你

一、 你没有再挽留 我也没有再回头 就这样 无风无雨也无晴 无疾而终二、 是我孤陋寡闻不知你心有人三、 如果作业有葬礼,全体学生定当盛装出席.四、 纵使我有千般好 你也看不到 因为你没有一双爱我的眼睛五、 原来暂时共你没缘分 来年先会变得更合衬六、 真的别回头 你有未来 你…

PHP 完整实战23种设计模式

PHP实战创建型模式 单例模式 工厂模式 抽象工厂模式 原型模式 建造者模式 PHP实战结构型模式 桥接模式 享元模式 外观模式 适配器模式 装饰器模式 组合模式 代理模式 过滤器模式 PHP实战行为型模式 模板模式 策略模式 状态模式 观察者模式 责任链模式 访问者模…

Diango博客--16.稳定易用的 Django 分页库,完善分页功能(二)

文章目录0.思路引导1.分页效果概述2.分页思路3.Django 第三方拓展&#xff1a;django-pure-pagination4.自定义模板0.思路引导 1&#xff09;在前面我们通过 Django Pagination 实现简单分页 中&#xff0c;我们实现了一个简单的分页导航。但效果有点差强人意&#xff0c;我们…

回归测试

在集成测试过程中&#xff0c;每当一个新模块结合进来时&#xff0c;程序就发生了变化&#xff1a;建立了新的数据流路径&#xff0c;可能出现了新的I/O操作&#xff0c;激活了新的控制逻辑。在集成测试的范畴中&#xff0c;回归测试是指重新执行已经做过的测试的某个子集&…

不同的写法 其中 1 2 (试了下 没有效果 ,先记载这里把)

转载于:https://www.cnblogs.com/kaibindirver/p/9145455.html

美国西北大学 计算机工程专业排名,[转载]美国西北大学计算机工程研究生最新专业排名...

对于打算去美国西北大学读研究生的学生来讲&#xff0c;美国西北大学研究生申请要求及美国西北大学研究生专业介绍是学生最关心的问题。本文香港介绍美国西北大学研究生申请要求及美国西北大学研究生的专业介绍&#xff0c;帮助更多的学生更好的了解美国西北大学。2016年西北大…

析构函数virtual与非virtual区别

作为通常的原则&#xff0c;如果一个类定义了虚函数&#xff0c;那么它的析构函数就应当是virtual的。因为定义了虚函数则隐含着&#xff1a;这个类会被继承&#xff0c;并且会通过基类的指针指向子类对象&#xff0c;从而得到多态性。 这个类可能会被继承&#xff0c;并且会…

Python:字典列表字符串方法测试

测试的一些Python中的关于字典、列表、字符串的使用方法&#xff0c;放在这里备查。整个测试代码和说明如下&#xff1a; # -*- coding: utf-8 -*- """Python:函数中全是指针传递&#xff0c;而任何变量都是给予一个指针指向一个内存空间"""impo…

什么是确认测试

确认测试也称为验收测试&#xff0c;它的目标是验证软件的有效性。 通常&#xff0c;验证指的是保证软件正确地实现了某个特定要求的一系列活动&#xff1b;确认指的是为了保证软件确实满足了用户需求而进行的一系列活动。 软件有效性的一个简单定义是&#xff1a;如果软件的功…

Diango博客--17.统计各个分类和标签下的文章数

文章目录0.思路引导1.Model 回顾2.数据库数据聚合3.使用 Annotate4.在模板中引用新增的属性0.思路引导 在我们的博客侧边栏有分类列表和标签列表&#xff0c;显示博客已有的全部文章分类。现在想在分类名和标签名后显示该分类或者标签下有多少篇文章&#xff0c;该怎么做呢&am…

HTTP协议中request报文请求方法和状态响应码

一个HTTP请求报文由4部分组成&#xff1a; 请求行&#xff08;request line&#xff09;请求头部&#xff08;header&#xff09;空行请求数据下图给出了请求报文的一般格式&#xff1a; 请求行中包括了请求方法&#xff0c;常见的请求方法有&#xff1a; GET&#xff1a;从服务…

计算机无法安装64位操作系统,为什么我的win7旗舰版service Pack 1 64位操作系统 无法安装(KB2670838) 这个更新...

您好&#xff01;我了解到您遇到关于这边的问题请问无法安装是否出现了什么错误代码提示呢&#xff1f;请参考以下的步骤解决按WindowsR打开cmd里使用下面的命令关闭相关的一些服务&#xff1a;net stop wuauservnet stop cryptSvcnet stop bitsnet stop msiserver完成后&#…

bmon:一个强大的网络带宽监视和调试工具

bmon 是类 Unix 系统中一个基于文本&#xff0c;简单但非常强大的 网络监视和调试工具&#xff0c;它能抓取网络相关统计信息并把它们以用户友好的格式展现出来。它是一个可靠高效的带宽监视和网速估测工具。 它能使用各种输入模块读取输入&#xff0c;并以各种输出模式显示输出…

函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)

关于函数的调用规则&#xff08;调用约定&#xff09;&#xff0c;大多数时候是不需要了解的&#xff0c;但是如果需要跨语言的编程&#xff0c;比如VC写的dll要delphi调用&#xff0c;则需要了解。 microsoft的vc默认的是__cdecl方式&#xff0c;而windows API则是__stdcall&a…

Linux 下的/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin区别

1、/bin 是所有用户都可以访问并执行的可执行程序。包括超级用户及一般用户。 供所有用户&#xff08;包括root用户和一般用户&#xff09;使用的基本命令&#xff0c;主要有cat,chmod,date,cp,bash等等常用的命令。 2、/usr/bin&#xff1a;系统预装的可执行程序&#xff0c;…

alpha测试和betal测试

如果一个软件是为许多客户开发的&#xff08;例如&#xff0c;向大众公开出售的盒装软件产品&#xff09;&#xff0c;那么绝大多数软件开发商都使用被称为Alpha测试和Beta测试的过程&#xff0c;来发现那些看起来只有最终用户才能发现的错误。 Alpha测试由用户在开发者的场所进…

计算机d盘无法格式化,四种方法解决D盘无法格式化问题

不少朋友系统出现故障&#xff0c;几乎都是选择重装系统的方法来解决问题。系统重装后&#xff0c;不少朋友觉得D盘没有什么重要的东西&#xff0c;就想将其格式化&#xff0c;可是系统出现windows无法格式该驱动器的提示&#xff0c;这是怎么回事呢&#xff1f;D盘无法格式化要…

sqlserver视图

作用 ①简化了操作&#xff0c;把经常使用的数据定义为视图。 ②安全性&#xff0c;用户只能查询和修改能看到的数据。 ③逻辑上的独立性&#xff0c;屏蔽了真实表的结构带来的影响。 对视图的修改&#xff1a;单表视图一般用于查询和修改&#xff0c;会改变基本表的数据&#…