对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等,这样会导致测试无法进行,为了可以对Controller进行测试,可以通过引入MockMVC进行解决。
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分别对应两种测试方式,即独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。对于我们来说直接使用静态工厂MockMvcBuilders创建即可。
下面就写一个简单的案例,告诉你是如何使用MockMvc进行Controller测试的。
第一步、创建项目
创建一个Maven项目(springboot-junit),并配置pom.xml,参照下面代码:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.lvgang</groupId> <artifactId>springboot-junit</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot-junit</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> </dependencies> </project> |
创建一个Controller类,我们在后面就测试空上Controller:
package org.lvgang; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/") public String hello(String name){ return "hello "+name; } } |
第二步、编写测试类
下面我们就是编写测试类了:
package org.lvgang; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; //SpringBoot1.4版本之前用的是SpringJUnit4ClassRunner.class @RunWith(SpringRunner.class) //SpringBoot1.4版本之前用的是@SpringApplicationConfiguration(classes = Application.class) @SpringBootTest(classes = App.class) //测试环境使用,用来表示测试环境使用的ApplicationContext将是WebApplicationContext类型的 @WebAppConfiguration public class HelloControllerTest { @Autowired private WebApplicationContext webApplicationContext; private MockMvc mockMvc; @Before public void setUp() throws Exception{ //MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc; mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();//建议使用这种 } @Test public void getHello() throws Exception{ /** * 1、mockMvc.perform执行一个请求。 * 2、MockMvcRequestBuilders.get("XXX")构造一个请求。 * 3、ResultActions.param添加请求传值 * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型 * 5、ResultActions.andExpect添加执行完成后的断言。 * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情 * 比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。 * 5、ResultActions.andReturn表示执行完成后返回相应的结果。 */ MvcResult mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/") .param("name","lvgang") .accept(MediaType.TEXT_HTML_VALUE)) // .andExpect(MockMvcResultMatchers.status().isOk()) //等同于Assert.assertEquals(200,status); // .andExpect(MockMvcResultMatchers.content().string("hello lvgang")) //等同于 Assert.assertEquals("hello lvgang",content); .andDo(MockMvcResultHandlers.print()) .andReturn(); int status=mvcResult.getResponse().getStatus(); //得到返回代码 String content=mvcResult.getResponse().getContentAsString(); //得到返回结果 Assert.assertEquals(200,status); //断言,判断返回代码是否正确 Assert.assertEquals("hello lvgang",content); //断言,判断返回的值是否正确 } } |
整个测试过程如下:
1、准备测试环境
2、通过MockMvc执行请求
3、添加验证断言
4、添加结果处理器
5、得到MvcResult进行自定义断言/进行下一步的异步请求
6、卸载测试环境
第三步、测试结果
通过执行HelloControllerTest,得到以下结果:
并且把整个返回结果都打印到了Console中:
MockHttpServletRequest: HTTP Method = GET Request URI = / Parameters = {name=[lvgang]} Headers = {Accept=[text/html]} Handler: Type = org.lvgang.HelloController Method = public java.lang.String org.lvgang.HelloController.hello(java.lang.String) Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 200 Error message = null Headers = {Content-Type=[text/html;charset=UTF-8], Content-Length=[12]} Content type = text/html;charset=UTF-8 Body = hello lvgang Forwarded URL = null Redirected URL = null Cookies = [] 通过以上代码,我们就完成了一个简单的案例。 |
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理