使用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 2023-06-15 22:32 zhangyukun 阅读(285) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
2022-06-15 JDK8 新特性 lamdda表达式 Stream 接口支持实例方法