SpringCloud单元测试【六】

SpringCloud的单元测试主要是依靠 Mock以及Mockito, 所以我们需要对Mock以及Mockito有一定的认识。

一、为什么要用MockMvc

  可能我们在测试控制层的代码都是启动服务器,在浏览器中输入URL,然后开始测试是否达到预期效果,发生错误的话,修改相关代码并重启服务器再次进行测试。分析一下这个过程,启动服务器-->打开浏览器-->输入URL-->等待返回结果-->修复bug-->重启服务器.....循环。
  其中的缺点也挺明显的,在浏览器输入URL的地址,如果是GET请求还好,POST请求或者DELETE请求怎么办?只能借助其他工具,通过命令行编写curl语句,或者借助谷歌浏览器的postman插件,亦或者自己在代码中通过编写相应httpClient方法来实现测试,但是这几种方法都较为麻烦,而且测试用例并不能较好的保存。再说一个缺点,代码修改后,往往需要再次重启服务器,等待启动完毕才能接下来的测试过程。
  如果tomcat服务器启动速度较慢,这将是一件非常痛苦的事情,测试验证也不方便,且依赖网络环境,这些原因导致测试起来很麻烦,而为了可以方便对Controller进行测试,且很好的保存和循环使用测试用例,则可以通过单元测试来解决,通过前面一篇文章,大家对于单元测试的便利性有了认识和体会,接下来通过引入MockMVC进行控制层的单元测试。

  MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。

二、示例演示

1. pom.xml中引入依赖

1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-test</artifactId> 4 <scope>test</scope> 5</dependency>

2. 编写测试类

在测试类前加上注解

1@RunWith(SpringRunner.class) 2@SpringBootTest(classes = EurekaClientApplication.class) //EurekaClientApplication是模块的启动类名 3@WebAppConfiguration 4@ContextConfiguration

再加上

1@Autowired 2private WebApplicationContext context; 3 4private MockMvc mvc;

再加上一个before

1@Before 2public void setUp() throws Exception { 3 mvc = MockMvcBuilders 4 .webAppContextSetup(context) 5 .build(); 6}

在真实需要测试的代码中加入

1@Test 2public void contextLoads() throws Exception { 3 MvcResult 4//groupManager访问路径 5//param传入参数 6result=mvc.perform(MockMvcRequestBuilders.post("/groupManager").param("pageNum","1").param("pageSize","10")).andReturn(); 7 MockHttpServletResponse response = result.getResponse(); 8 String content = response.getContentAsString(); 9 List<JtInfoDto> jtInfoDtoList = GsonUtils.toObjects(content, new TypeToken<List<JtInfoDto>>() {}.getType()); 10 for(JtInfoDto infoDto : jtInfoDtoList){ 11 System.out.println(infoDto.getJtCode()); 12 } 13}

3. 数据库回滚

在测试类上添加注解@Rollback,同时测试方法加上注解@Transactional。

如果不希望回滚 将rollback改为false即可

4. 完整的测试代码

1@RunWith(SpringRunner.class) 2@SpringBootTest(classes = EurekaClientApplication.class) 3@WebAppConfiguration 4@ContextConfiguration 5public class EurekaClientApplicationTests { 6 7 @Autowired 8 private WebApplicationContext context; 9 10 private MockMvc mvc; 11 12 @Before 13 public void setUp() throws Exception { 14 mvc = MockMvcBuilders 15 .webAppContextSetup(context) 16 .build(); 17 } 18 19 @Test 20 public void contextLoads() throws Exception { 21 MvcResult result=mvc.perform(MockMvcRequestBuilders.post("/groupManager").param("pageNum","1").param("pageSize","10")).andReturn(); 22 MockHttpServletResponse response = result.getResponse(); 23 String content = response.getContentAsString(); 24 List<JtInfoDto> jtInfoDtoList = GsonUtils.toObjects(content, new TypeToken<List<JtInfoDto>>() {}.getType()); 25 for(JtInfoDto infoDto : jtInfoDtoList){ 26 System.out.println(infoDto.getJtCode()); 27 } 28 } 29 30}

注意:我们大多数的时候是往控制层controller传递的不是一个简单的参数,可能是一个Map或一个实体类,发现怎么都传不过去,解决方法如下:

在发送请求的时候,我们使用json的参数格式 

1    Map params = new HashMap(); 2 params.put("name", "西瓜"); 3 params.put("unit","斤"); 4 params.put("price", "12.88"); 5 String requestJson = JSONObject.toJSONString(params); 6 MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/good/save") 7 .contentType(MediaType.APPLICATION_JSON).content(requestJson)) 8 .andDo(MockMvcResultHandlers.print()) 9 .andExpect(MockMvcResultMatchers.status().is(200)) 10 .andReturn(); 11 result.getResponse().setCharacterEncoding("UTF-8"); 12 System.out.println(result.getResponse().getContentAsString());

然后controller的参数添加@RequestBody注解。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )