使用MockMvc测试 Controller

使用MockMvc可以做到controller层的测试。

  • 如果直接注入controller,然后调用指定的方法是不会通过拦截器等外层组件的,
  • 使用mockMvc可以触发外层组件,模拟真实的场景的情况。
package com.lomi.mockMvc;

import cn.hutool.json.JSONUtil;
import com.lomi.controller.MockMvcController;
import com.lomi.controller.TestController;
import com.lomi.entity.Goods;
import com.lomi.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
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.HttpHeaders;
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.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import java.sql.SQLOutput;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
public class MockMvcTest {

    // 自己写的controller
    @Autowired
    private MockMvcController mockMvcController;

    @Autowired
    WebApplicationContext context;


    //在before里面初始化
    private MockMvc mockMvc;

    @Before
    public void before() {
        //初始化mockMvc
        //可以测试单个controller
        //mockMvc = MockMvcBuilders.standaloneSetup(mockMvcController).build();

        //可以测试所有controller
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }


    /**
     * get
     *
     * @throws Exception
     */
    @Test
    public void t1() throws Exception {
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
                        .get("/mockmvc/getReq")
                )
                //期望的响应状态200
                .andExpect(MockMvcResultMatchers.status().isOk())
                //打印请求过程
                .andDo(MockMvcResultHandlers.print())
                //返回结果
                .andReturn();


        log.warn("响应参数:{}",mvcResult.getResponse().getContentAsString());
    }


    /**
     * get带参数
     *
     * @throws Exception
     */
    @Test
    public void t2() throws Exception {
        MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.get("/mockmvc/getReq")
                        //设置请求参数
                        .param("name","张三")
        ).andExpect(MockMvcResultMatchers.status().isOk())
        .andDo(MockMvcResultHandlers.print())
        .andReturn();

        log.warn("响应参数:{}",mvcResult.getResponse().getContentAsString());
    }


    /**
     * post,json请求带参数,返回json
     *
     * @throws Exception
     */
    @Test
    public void t3() throws Exception {
        Goods goods = Goods.randomGoods();

        MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.post("/mockmvc/postJson")
                        //设置请求头ContentType
                        .contentType(MediaType.APPLICATION_JSON_VALUE)
                        //设置请求体
                        .content(JSONUtil.toJsonStr( goods ))
                        //设置请求头accept
                        .header(HttpHeaders.ACCEPT,"application/json")
        ).andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();

        log.warn("响应参数:{}",mvcResult.getResponse().getContentAsString());
    }



    /**
     * post,json请求带参数,返回xml
     *
     * @throws Exception
     */
    @Test
    public void t4() throws Exception {
        Goods goods = Goods.randomGoods();

        MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.post("/mockmvc/postJson")
                        //设置请求头ContentType
                        .contentType(MediaType.APPLICATION_JSON_VALUE)
                        .content(JSONUtil.toJsonStr( goods ))
                        //设置请求头accept
                        .header(HttpHeaders.ACCEPT,"application/xml")
        ).andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();

        log.warn("响应参数:{}",mvcResult.getResponse().getContentAsString());
    }

    /**
     * post,json请求带参数,返回xml
     *
     * @throws Exception
     */
    @Test
    public void t5() throws Exception {
        Goods goods = Goods.randomGoods();

        MvcResult mvcResult = mockMvc.perform(
                        MockMvcRequestBuilders.post("/mockmvc/postFrom")
                                .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                                .content(JSONUtil.toJsonStr( goods ))
                                .header(HttpHeaders.ACCEPT,"application/xml")
                ).andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();

        log.warn("响应参数:{}",mvcResult.getResponse().getContentAsString());
    }



}

MockmvcController接口代码

package com.lomi.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.lomi.annotation.ShowParam2;
import com.lomi.entity.Goods;
import com.lomi.websocket.SimpleWebSocket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;


@Api(tags="mockmvc测试")
@RestController
@RequestMapping(value = "/mockmvc")
public class MockMvcController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(MockMvcController.class);

	@ApiOperation(value = "get请求")
	@GetMapping("/getReq")
	@ShowParam2
	public String getReq(@RequestParam(required = false) String name) {

		logger.info("getReq 参数{}", name );
		return "OK";
	}


	@ApiOperation(value = "post json格式")
	@PostMapping("/postJson")
	@ShowParam2
	public Goods postJson(@RequestBody Goods goods) {
		logger.warn("postJson 请求参数是{}",goods);
		return goods;
	}

	@ApiOperation(value = "post from格式")
	@PostMapping("/postFrom")
	@ShowParam2
	public Goods postFrom( Goods goods) {
		logger.warn("postFrom 请求参数是{}",goods);
		return goods;
	}

}

mockMvc位于spring-test包,如果你导入spring-boot-starter-test的scope是test那么只能在测试用例里面使用

在mockMvc的类声明上面就有用法的例子,spring 3.2 以后就有特性,下面是 MockMvc源码的头部片段

/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.test.web.servlet;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.springframework.beans.Mergeable;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * <strong>Main entry point for server-side Spring MVC test support.</strong>
 *
 * <h3>Example</h3>
 *
 * <pre class="code">
 * import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
 * import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
 * import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
 *
 * // ...
 *
 * WebApplicationContext wac = ...;
 *
 * MockMvc mockMvc = webAppContextSetup(wac).build();
 *
 * mockMvc.perform(get("/form"))
 *     .andExpect(status().isOk())
 *     .andExpect(content().mimeType("text/html"))
 *     .andExpect(forwardedUrl("/WEB-INF/layouts/main.jsp"));
 * </pre>
 *
 * @author Rossen Stoyanchev
 * @author Rob Winch
 * @author Sam Brannen
 * @since 3.2
 */
public final class MockMvc {

	static final String MVC_RESULT_ATTRIBUTE = MockMvc.class.getName().concat(".MVC_RESULT_ATTRIBUTE");

	private final TestDispatcherServlet servlet;

	private final Filter[] filters;

	private final ServletContext servletContext;

	@Nullable
	private RequestBuilder defaultRequestBuilder;

	@Nullable
	private Charset defaultResponseCharacterEncoding;

	private List<ResultMatcher> defaultResultMatchers = new ArrayList<>();

	private List<ResultHandler> defaultResultHandlers = new ArrayList<>();

posted on   zhangyukun  阅读(285)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2022-06-15 JDK8 新特性 lamdda表达式 Stream 接口支持实例方法

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示