spring boot(三)Junit 测试controller
Junit测试Controller(MockMVC使用),传输@RequestBody数据解决办法
一、单元测试的目的
简单来说就是在我们增加或者改动一些代码以后对所有逻辑的一个检测,尤其是在我们后期修改后(不论是增加新功能,修改bug),都可以做到重新测试的工作。以减少我们在发布的时候出现更过甚至是出现之前解决了的问题再次重现。
这里主要是使用MockMvc对我们的系统的Controller进行单元测试。
对数据库的操作使用事务实现回滚,及对数据库的增删改方法结束后将会还远数据库。
二、MockMvc的使用
1、首先我们上一个例子,
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;/*** Created by zhengcanrui on 16/8/11.*/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring/applicationContext-*xml"})//配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用 @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) @Transactional@WebAppConfiguration public class Test {//记得配置log4j.properties ,的命令行输出水平是debugprotected Log logger= LogFactory.getLog(TestBase.class);protected MockMvc mockMvc;@Autowiredprotected WebApplicationContext wac;@Before() //这个方法在每个方法执行之前都会执行一遍public void setup() {mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); //初始化MockMvc对象}@org.junit.Testpublic void getAllCategoryTest() throws Exception {String responseString = mockMvc.perform(get("/categories/getAllCategory") //请求的url,请求的方法是get.contentType(MediaType.APPLICATION_FORM_URLENCODED) //数据的格式.param("pcode","root") //添加参数).andExpect(status().isOk()) //返回的状态是200.andDo(print()) //打印出请求和相应的内容.andReturn().getResponse().getContentAsString(); //将相应的数据转换为字符串System.out.println("--------返回的json = " + responseString);}}
Spring MVC的测试往往看似比较复杂。其实他的不同在于,他需要一个ServletContext来模拟我们的请求和响应。但是Spring也针对Spring MVC 提供了请求和响应的模拟测试接口,以方便我们的单元测试覆盖面不只是service,dao层。
2、代码解释:
@webappconfiguration是一级注释,用于声明一个ApplicationContext集成测试加载WebApplicationContext。作用是模拟ServletContext
@ContextConfiguration:因为controller,component等都是使用注解,需要注解指定spring的配置文件,扫描相应的配置,将类初始化等。
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) @Transactional
上面两句的作用是,让我们对数据库的操作会事务回滚,如对数据库的添加操作,在方法结束之后,会撤销我们对数据库的操作。
为什么要事务回滚?
- 测试过程对数据库的操作,会产生脏数据,影响我们数据的正确性
- 不方便循环测试,即假如这次我们将一个记录删除了,下次就无法再进行这个Junit测试了,因为该记录已经删除,将会报错。
- 如果不使用事务回滚,我们需要在代码中显式的对我们的增删改数据库操作进行恢复,将多很多和测试无关的代码
方法解析:
- perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
- get:声明发送一个get请求的方法。MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根据uri模板和uri变量值得到一个GET请求方式的。另外提供了其他的请求的方法,如:post、put、delete等。
- param:添加request的参数,如上面发送请求的时候带上了了pcode = root的参数。假如使用需要发送json数据格式的时将不能使用这种方式,可见后面被@ResponseBody注解参数的解决方法
- andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确(对返回的数据进行的判断);
- andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台(对返回的数据进行的判断);
- andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理(对返回的数据进行的判断);
注意事项:
- 在mac上使用log4j是,假如使用了${catalina.home}需要注意,mac不会去找到tomcat所在的路径,直接回到根路径 “/”,而正常情况下,根路径是没有写权限的,需要使用管理员赋权限。
- log4j在配置完成之后,需要设置起打印日志的级别,假如没有设置,在Junit中,将无法打印日志。
3、后台的返回数据中,最好带上我们对数据库的修改的结果返回的前端。
为什么要在data中返回一个修改或者添加的对象
- 将数据返回给前端,前端容易判断数据是否添加或者修改成功
- 更新或者添加完数据经常需要刷新页面,将数据直接给了前端,前端不用再发一个请求来获取
- 单元测试的时候,能对数据库的DDL(增删改)操作的时候,我们能对数据进行审核,从何判断我们的操作是否是成功的。如下面的例子:
我们发送一个添加操作,添加一个SoftInfo对象,SoftInfo类定义如下:
public class SoftInfo {private String id;private String name; }
添加完之后,由于我们进行了单元测试的事务回滚,我们将不能再数据库中看我们我们的的添加操作,无法判断操作是否成功。
为了解决上面的问题,我们可以在返回的json的数据中添加一个“data”字段,解析该json中的data字段数据,判断我们的添加操作是否成功的。json格式如下:
{"status":200,"data":{"id":"2","name":"测试"} }
我们可以使用andExpect方法对返回的数据进行判断,用“$.属性”获取里面的数据,如我要获取返回数据中的"data.name",可以写成"$.data.name"。下面的例子是判断返回的data.name=“测试”。
三、遇到的问题
1、发送一个被@ResponseBody标识的参数,一直到400错误。 即无法发送一个json格式的数据到Controller层。
解决方法1:
SoftInfo softInfo = new SoftInfo(); //设置值 ObjectMapper mapper = new ObjectMapper();ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();java.lang.String requestJson = ow.writeValueAsString(softInfo);String responseString = mockMvc.perform( post("/softs").contentType(MediaType.APPLICATION_JSON).content(requestJson)).andDo(print()).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
解决方法2:使用com.alibaba.fastjson.JSONObject将对象转换为Json数据
SoftInfo softInfo = new SoftInfo(); //。。。设置值String requestJson = JSONObject.toJSONString(folderInfo);String responseString = mockMvc.perform( post("/softs").contentType(MediaType.APPLICATION_JSON).content(requestJson)).andDo(print()).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
注意上面contentType需要设置成MediaType.APPLICATION_JSON,即声明是发送“application/json”格式的数据。使用content方法,将转换的json数据放到request的body中。
2、java.lang.NoClassDefFoundError: com/jayway/jsonpath/InvalidPathException
缺少了jar包:
可以添加一下的maven依赖
<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>0.8.1</version><scope>test</scope></dependency><dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path-assert</artifactId><version>0.8.1</version><scope>test</scope></dependency>
学习连接:https://www.cnblogs.com/0201zcr/p/5756642.html
转载于:https://www.cnblogs.com/PollyLuo/p/9630822.html
spring boot(三)Junit 测试controller相关推荐
- Spring Boot JUnit 测试 Controller
Spring Boot JUnit 测试 Controller Controller层代码如下: @RestController public class HelloController {Logge ...
- Spring Boot中的测试
文章目录 简介 添加maven依赖 Repository测试 Service测试 测试Controller @SpringBootTest的集成测试 Spring Boot中的测试 简介 本篇文章我们 ...
- Spring Boot 应用的测试
Spring Boot 应用的测试 <Spring Boot 实战开发>(陈光剑) -- 基于 Gradle + Kotlin的企业级应用开发最佳实践 本书写到这里,Spring Boot ...
- boot spring test 文档_Spring、Spring Boot 和 TestNG 测试指南 ( 3 )
原标题:Spring.Spring Boot 和 TestNG 测试指南 ( 3 ) 来源:chanjarster, github.com/chanjarster/spring-test-exampl ...
- 搭建spring boot环境并测试一个controller
Idea搭建spring boot环境 一.新建项目 二.起步依赖 三.编写SpringBoot引导类 四.编写Controller 五.热部署 一.新建项目 1.新建project 2.选择Spri ...
- spring boot三:spring boot的hello, world
一: 创建一个maven工程(jar) 1. 打开idea,创建新工程 2. 选择maven----> project_sdk,选择安装的jdk 3.进入idea后,点击"enable ...
- 【星云测试】开发者测试-采用精准测试工具对Spring Boot应用进行测试
2019独角兽企业重金招聘Python工程师标准>>> 简介:本文主要介绍把现今主流的springboot框架项目和精准测试工具进行结合和应用,通过精准测试的数据穿透.数据采集.测试 ...
- 绝了!这款工具让 Spring Boot 不在需要 Controller、Service、DAO、Mapper 了
来源:my.oschina.net/ta8210/blog/3234639 Dataway 是基于 DataQL 服务聚合能力,为应用提供的一个接口配置工具.使得使用者无需开发任何代码就配置一个满 ...
- Spring、Spring Boot和TestNG测试指南 - 测试@Configuration
Github地址 在Spring引入Java Config机制之后,我们会越来越多的使用@Configuration来注册Bean,并且Spring Boot更广泛地使用了这一机制,其提供的大量Aut ...
最新文章
- html页面引入另一个html页面
- 通过cookies跳过验证码登陆页面,直接访问网站的其它URL
- 看过漫改,但你看过「改漫」吗?AI 一键让影视变漫画
- MVC应用程序播放RealPlayer(rmvb)视频
- matlab自动给变量命名
- iOS线程锁中你还不知道的内容
- static函数与普通函数区别
- aspose 转pdf表格大小乱了_自己写了一个小工具类:pdf转word,没有页数和大小限制,保真!...
- ZT: Some lesser-known truths about programming
- 剑指offer(C++)-JZ33:二叉搜索树的后序遍历序列(数据结构-树)
- 线上python课程一般多少钱-python培训班一般多少钱?一篇文章告诉你
- html5鼠标悬停图片变淡,鼠标移动悬停在图片上图片变色或半透明变化效果实现...
- html自我介绍怎么弄,用html设计一个自我介绍的静态网页
- 如何修改网页视频播放倍速?(最高16倍速)
- VMware上传超过4GB文件失败
- DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理
- 达州中学高考2021成绩查询,2020达州高考成绩揭晓,恭喜恭喜!另附成绩统计表...
- 外贸找客户软件-Bitrecover Email Extractor
- 怎么从微信群聊中引流?如何从群聊进行引流?微信群怎么引流
- 4月10日第七次CCF