Springboot08-项目单元测试(接口测试)
Springboot08-项目单元测试(接口测试)
前言
1-本文重点在于源码层面,分析Springboot单元测试的使用,对于其中的注解、方法等,不会仔细分析;
2-本文项目实例相关配置:Java-1.8; Springboot-1.5.12.RELEASE,使用的是Intellij
正文
1- JUnitGenerator V2.0 单元测试代码自动生成插件的使用
因为插件的安装和使用,比较简单,见参考资料-1,或自行百度;这里不再赘述;
注意:JUnitGenerator主要是可以针对需要测试的类,在test目录下快速生成对应的测试类,而测试的具体实现还是要手动处理;
2-最简单的单元测试,源码如下:
package com.hs.web.controller.system.login; import net.sf.json.JSONObject;@RunWith(SpringRunner.class) @SpringBootTest(classes= FrameworkApplication.class) public class LoginControllerTest {private MockMvc mvc;@Autowiredprivate WebApplicationContext context;@Beforepublic void setUp() throws Exception {mvc = MockMvcBuilders.webAppContextSetup(context).build();}@Testpublic void login() throws Exception{//1-封装请求参数Map<String, String> paramMap = new HashMap<>();paramMap.put("openid", "tangyujie");JSONObject jsonObject = JSONObject.fromObject(paramMap);//2-构建请求RequestBuilder builder = MockMvcRequestBuilders.post("/api/shop/login").content(jsonObject.toString()).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON);//3-执行请求 mvc.perform(builder).andExpect(status().isOk()).andExpect(jsonPath("code").value(200)).andDo(MockMvcResultHandlers.print());}@Afterpublic void after(){} }
如果只测试一个接口,或者只测试一个类,那么上面的方法基本上已经可以满足需求,但是针对上百个类或方法的情况,则会出现大量的代码冗余,并且还需要手动启动每一个测试类,这明显是不可取的;
所以,在上述简单的单元测试方法上,进行封装
3-封装通用的单元测试模板
单元测试模板可以满足如下需求:
- 抽取公用的方法和注解,优化代码,实现代码复用,也方便维护
- 多个单元测试类,一个启动入口,实现一键测试
接口测试的步骤
- 请求数据
- 构造请求
- 执行请求及判断请求结果
- 处理返回参数(本步骤可以没有)
备注:本项目的接口因为供App使用,(除了登录接口)其他都是要传token(跟在UTL?后面)
源码如下
测试模板目录
BaseTest抽象类,用于封装通用方法
package com.hs.api.base;import net.sf.json.JSONObject;public abstract class BaseTest {//1-1-构建post请求protected RequestBuilder getPostBuilder(String url, JSONObject jsonObject){RequestBuilder builder = MockMvcRequestBuilders.post(url).content(jsonObject.toString()).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON);return builder;}//1-2-构建get请求protected RequestBuilder getGetBuilder(String url){RequestBuilder builder = MockMvcRequestBuilders.get(url).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON);return builder;}//2-执行请求protected MvcResult performMVC(MockMvc mvc, RequestBuilder bulider ){try {MvcResult mvcResult = mvc.perform(bulider).andExpect(status().isOk()).andExpect(jsonPath("code").value(200))//.andDo(MockMvcResultHandlers.print()) .andReturn();return mvcResult;} catch (Exception e) {e.printStackTrace();return null;}} }
BaseControllerTest类,继承 BaseTest抽象类,且是所有单元测试类的父类, 使用了@RunWith、@SpringBootTest等类注解,并且实现了通用的@Before和@After方法,以及登录接口的具体实现,主要是从普通的单元测试类中提取出公有的因素
package com.hs.api.base; import net.sf.json.JSONObject; //所有单元测试类的基类 @RunWith(SpringRunner.class) @SpringBootTest(classes= FrameworkApplication.class) @WebAppConfiguration public abstract class BaseControllerTest extends BaseTest {@Autowiredprotected WebApplicationContext context;protected MockMvc mvc ;protected static String shopToken = null;//apptoken @Beforeprotected void setUp() throws Exception {System.out.println("controller test is starting");mvc = MockMvcBuilders.webAppContextSetup(context).build();if(shopToken == null){System.out.println("获取shoptoken");shopToken = shopLogin();}}@Afterprotected void tearDown(){System.out.println("controller test is over");}//1-App登录操作protected String shopLogin() {//1-请求数据String url = "/api/shop/login";LoginReq loginReq = new LoginReq("tangyujie");JSONObject content = JSONObject.fromObject(loginReq);//2-构造请求RequestBuilder postBuilder = getPostBuilder(url, content);try {//3-执行请求-及判断请求结果MvcResult mvcResult = performMVC(mvc, postBuilder);//4-c处理返回参数,获取shopTokenString contentAsString = mvcResult.getResponse().getContentAsString();//System.out.println("contentAsString=== " + contentAsString);JSONObject jsonObject = JSONObject.fromObject(contentAsString);Map<String,Class<?>> classMap = new HashMap<String,Class<?>>();classMap.put("data", LoginRes.class);TestShopLoginRes entity = (TestShopLoginRes)JSONObject.toBean(jsonObject,TestShopLoginRes.class,classMap);//System.out.println("entity: " + entity);return entity .getData().getShopToken();} catch (Exception e) {e.printStackTrace();return null;}}}
ApiShopLoginControllerTest类,登录的接口的测试类,继承BaseControllerTest类;本类包含一个POST接口实例
package com.hs.api.shopapp.controller;public class ApiShopLoginControllerTest extends BaseControllerTest{//POST请求示例//1-登录 @Testpublic void loginOrRegister() {shopLogin();} }
ApiShopMemberControllerTest类,用户接口的测试类,继承BaseControllerTest类;本类包含一个GET接口实例
package com.hs.api.shopapp.controller; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;public class ApiShopMemberControllerTest extends BaseControllerTest{//GET请求示例 @Testpublic void getMemberShopInfo() {//1-请求参数System.out.println("shopToken == " + shopToken);String url = "/api/shop/member/detail?shopToken=" + shopToken;//2-构建请求RequestBuilder getBuilder = getGetBuilder(url);try {//3-执行请求MvcResult mvcResult = performMVC(mvc, getBuilder);System.out.println("getMemberShopInfo mvcResult: " + mvcResult);} catch (Exception e) {e.printStackTrace();}}}
TestSuits类,本类没有具体的方法,唯一的作用是作为启动入口,测试全部测试类的方法
package com.hs.api;import org.junit.runner.RunWith; import org.junit.runners.Suite;//单元测试总入口,在@Suite.SuiteClasses里面添加需要测试的测试类 @RunWith(Suite.class) @Suite.SuiteClasses({ApiShopLoginControllerTest.class,ApiShopMemberControllerTest.class }) public class TestSuits { }
以下是模板用到的实体类POJO,主要是用户封装请求参数或返回参数,注意实体类和JSON字符串之间的转换
//请求参数实体类 public class LoginReq {private String openid;//openidpublic LoginReq() {}//省略geter和setter方法 }//返回参数实体父类 package com.hs.api.common;public class TestResponseEntity {public int code;public String message;public TestResponseEntity() {}//省略geter和setter方法 } //登录接口返回参数实体类(两个,相互嵌套关系)public class TestShopLoginRes extends TestResponseEntity {private LoginRes data;public TestShopLoginRes() {}public TestShopLoginRes(LoginRes data) {this.data = data;}//省略geter和setter方法@Overridepublic String toString() {return "TestShopLoginRes{" +"data=" + data +'}';} }public class LoginRes {private Long shopId;// private int mobileExistFlag;//手机号是否存在private String shopToken;// private int vipFlag;//是否是会员public LoginRes() {} //省略geter和setter方法@Overridepublic String toString() {return "LoginRes{" +"shopId=" + shopId +", mobileExistFlag=" + mobileExistFlag +", shopToken='" + shopToken + '\'' +", vipFlag=" + vipFlag +'}';} }
以下是实例中测试的实际接口类
//登录接口类 @RestController @RequestMapping(value="/api/shop/login") public class ApiShopLoginController extends ApiShopBaseController {//1-登陆或注册@RequestMapping(value="",method = RequestMethod.POST,produces = {JSON_UTF8})public String loginOrRegister(@RequestBody LoginReq loginReqt){//省略业务 }}//用户接口类 @RestController @RequestMapping(value="/api/shop/member") public class ApiShopMemberController extends ApiShopBaseController {//1-店主基本信息@RequestMapping(value = { "/detail" }, method={RequestMethod.GET},produces = {JSON_UTF8})public String getMemberShopInfo() throws ServerSqlErrorException {//省略业务 } }
参考文献:
1-JUnitGenerator使用方法:http://www.pianshen.com/article/516640707/
2-测试用例整合:https://blog.csdn.net/weixin_39800144/article/details/79241620
3-返回参数处理:https://blog.csdn.net/qq_16513911/article/details/83018027
转载于:https://www.cnblogs.com/wobuchifanqie/p/10445461.html
Springboot08-项目单元测试(接口测试)相关推荐
- 使用pytest对django项目单元测试
2019独角兽企业重金招聘Python工程师标准>>> 背景 使用django开发了个人博客,欲单元测试,后遍寻网络,然相关资料甚少,遂成此文,望对汝有所助 环境 pytest py ...
- websocket导致spring boot 项目单元测试启动失败的问题解决
背景 一个项目中需要实时的向前端展示数据变化,因此使用websocket.但是在项目中增加websocket后,功能没有问题,但是之前写的单元测试代码都无法运行.(代码和报错贴出来,如下,可以忽略) ...
- Spring Boot基础学习笔记02:Spring Boot项目单元测试、热部署与原理分析
文章目录 零.学习目标 1.掌握Spring Boot单元测试实现 2.掌握Spring Boot热部署实现 3.熟悉Spring Boot基本原理 一.Spring Boot单元测试 (一)Spri ...
- Spring的maven项目单元测试报错 : Error:java:JDK isn't specified for module
单元测试报错,跑不起来,报错如下: Error:java:JDK isn't specified for module 原来把 . idea 目录删除没有重启项目,重启项目 以后刷新maven: 点 ...
- 解读Android官方MVP项目单元测试
Google在3月份推出了一个项目,用来介绍Android MVP架构的各种组合,可以认为是官方在这方面的最佳实践.令人称道的是除了MVP本身之外,这些工程配备了极其完善的单元测试用例,学习价值极高. ...
- 【30天学会接口自动化测试】接口自动化测试之实际项目做接口测试(6)
整理了一些软件测试方面的资料.面试资料(接口自动化.web自动化.app自动化.性能安全.测试开发等),有需要的小伙伴可以文末加入我的学习交流qun,无套路自行领取~ 1.从实际项目出发分析测试结果处 ...
- springboot项目编写单元测试_SpringBoot项目单元测试(示例代码)
前一段时间,有朋友问到springboot运用如何进行单元测试,结合LZ公司的实际运用,这里给大家描述一下三种单元测试的方式. 1.约定 单元测试代码写在src/test/java目录下 单元测试类命 ...
- SpringBoot 项目单元测试
SpringBoot 单元测试方法 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId>&l ...
- IDEA中Maven项目创建单元测试(JUnit4)
文章目录 IDEA中Maven项目单元测试(JUnit4)记录 具体步骤 可能遇到的问题 后记 IDEA中Maven项目单元测试(JUnit4)记录 具体步骤 工具:idea2021.3版本,mave ...
最新文章
- linux获取近一小时日志,Linux分析日志获取最多访问的前10个IP
- JDK 10 的 109 项新特性
- JavaScript中的私有成员
- 2021暑假每日一题 【week2 完结】
- IHS Infonetics:网络运营商进军SDN
- 第7步 mybatis-generator dao层生成器
- JAVA中数字格式异常,java - Java数字格式异常 - 堆栈内存溢出
- 分析器错误信息: 未能加载类型命名空间.类... ---小结
- 小米10正式发布:3999元起!
- dva/dynamic
- github leaf项目怎么用_这份GitHub上价值49K的SpringBoot2+Thymeleaf企业应用实战,真香...
- 谷歌原数据保护团队技术主管:零信任实践分享
- 【BZOJ】【P3110】【ZJOI2013】【K大数查询】【题解】【树套树】
- 复旦大学高等代数学习指导书(白皮书)的评价
- 对透明表、簇表的理解
- 一键命令测试云主机的带宽
- mac 在调度中心关闭软件
- Cisco服务器http显示内容,IOS HTTP服务器的AAA控制
- qq浏览器HTML5在哪,qq浏览器wifi助手功能在哪里?
- 理论力学知识要点(九)