SpringMVC Mock测试实现原理及实现过程详解

什么是mock测试?

  在测试过程中,对于某些不容易构成或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,就是Mock测试。

  Servlet、Request、Response等Servlet API相关对象本来就是由Servlet容器(Tomcat)创建的。

  这个虚拟的对象就是Mock对象。

  Mock对象是真实对象在调试期间的代替品。

为什么使用Mock测试?

  • 避免开发模块之间的耦合
  • 轻量、简单、灵活

MockMVC介绍

MockMvcBuilder

  他是用来构造MockMVC的构造器

  主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分别对应之前的两种测试方式。

  我们直接使用静态工厂MockMvcBuilders创建即可。

MockMvcBuilders

  负责创建MockMvcBuilder对象

  有两种创建方式

    1、standaloneSetup(Object... controllers)

    2、webAppContextSetup(WebApplicationContext wac):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc

MockMvc

  对于服务器端的Spring MVC测试支持主入口点。

  通过MockMvcBuilder构造

  MockMvcBuilder由MockMvcBuilders的静态方法去构造。

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

ResultActions

andExpect

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

andDo

  添加ResultHandler结果处理器,比如调试时打印结果到控制台;

andReturn

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

MockMvcRequestBuilders

  • 用来构造请求
  • 主要由两个子类MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(如文件上传),即用来Mock客户端请求需要的所有数据。

MockMvcResultMatchers

  • 用来匹配执行完请求后的结果验证
  • 如果匹配失败将抛出相应的异常
  • 包含了很多验证API方法

MockMvcResultHandlers

  • 结果处理器,表示要对结果做点什么事情
  • 比如此处使用MockMvcResultHandlers.print()输出整个相应结果信息。

MvcResult

  单元测试执行结果,可以针对执行结果进行自定义验证逻辑。

MocMvc的使用

添加依赖

    <!-- spring 单元测试组件包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
 
    <!-- 单元测试Junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

测试类

TestMockMVC.java

package com.cyb.ssm.controller.test;

import org.junit.Before;
import org.junit.Test;
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.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

//@WebAppConfiguration:可以在单元测试的时候,不用启动Servlet容器,就可以获取一个Web应用上下文
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/*.xml")
@WebAppConfiguration
public class TestMockMVC {
  @Autowired
  private WebApplicationContext wac;
  private MockMvc mockMvc;

  @Before
  public void Setup() {
    // 初始化一个MockMVC对象的方式有两种:单独设置、web应用上下文设置
    // 建议使用web应用上下文设置
    mockMvc = new MockMvcBuilders().webAppContextSetup(wac).build();
  }

  @Test
  public void test() throws Exception {
    // 通过perform去执行一个Http请求
    // andExpect:通过该方法,判断请求执行是否成功
    // andDo:对请求之后的结果,进行输出
    MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/item/showEdit").param("id", "1"))
        .andExpect(MockMvcResultMatchers.view().name("item/item-edit"))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andDo(MockMvcResultHandlers.print())
        .andReturn();
    System.out.println("===============");
    System.out.println(result.getHandler());
  }
}

SpringMVC Mock测试实现原理及实现过程详解

扫一扫手机访问