SpringBoot应用的集成测试
一、概念和定义
进行软件开发的时候,我们会写很多代码,不过,再过六个月(甚至一年以上)你知道自己的代码怎么运作么?
通过测试(单元测试、集成测试、接口测试)可以保证系统的可维护性,当我们修改了某些代码时,通过回归测试可以检查是否引入了新的bug。
总的来说,测试让系统不再是一个黑盒子,让开发人员确认系统可用。
二、新建测试项目
1、test类
PersonApplicationTest.java,内容是:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = PersonApplication.class)
public class PersonApplicationTests {
@Test
public void contextLoads() {
}
}
2、pom依赖
在pom文件中增加spring-boot-starter-test依赖,添加jsonPath依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
3、在PersonApplicationTest中添加测试用例
package com.tianhe.example.Person;
import com.test.Person.domain.Book;
import com.test.Person.repository.BookRepository;
import org.junit.Before;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = PersonApplication.class)
@WebIntegrationTest("server.port:0")
public class PersonApplicationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private BookRepository bookRepository;
@Value("${local.server.port}")
private int port;
private MockMvc mockMvc;
private RestTemplate restTemplate = new TestRestTemplate();
@Before
public void setupMockMvc() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void contextLoads() {
assertEquals(1, bookRepository.count());
}
@Test
public void webappBookIsbnApi() {
Book book = restTemplate.getForObject("http://localhost:" + port +"/books/9876-5432-1111", Book.class);
assertNotNull(book);
assertEquals("中文测试", book.getPublisher().getName());
}
@Test
public void webappPublisherApi() throws Exception {
mockMvc.perform(get("/publishers/1")
.accept(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(content().string(containsString("中文测试")))
.andExpect(jsonPath("$.name").value("中文测试"));
}
}
二、spring boot项目的代码覆盖率
1、使用cobertura
参考项目的github地址:spring boot template
# To create test coverage reports (in target/site/cobertura)
mvn clean cobertura:cobertura test
cobertura统计代码覆盖率
单击某个类进去,可以看到详细信息
分析
首先分析在PersonApplicationTests类中用到的注解:
@RunWith(SpringJUnit4ClassRunner.class),这是JUnit的注解,通过这个注解让SpringJUnit4ClassRunner这个类提供Spring测试上下文。
@SpringApplicationConfiguration(classes = PersonApplication.class),这是Spring Boot注解,为了进行集成测试,需要通过这个注解加载和配置Spring应用上下文。这是一个元注解(meta-annoation),它包含了@ContextConfiguration( loader = SpringApplicationContextLoader.class)这个注解,测试框架通过这个注解使用Spring Boot框架的SpringApplicationContextLoader加载器创建应用上下文。
@WebIntegrationTest("server.port:0"),这个注解表示当前的测试是集成测试(integration test),因此需要初始化完整的上下文并启动应用程序。这个注解一般和@SpringApplicationConfiguration一起出现。server.port:0指的是让Spring Boot在随机端口上启动Tomcat服务,随后在测试中程序通过@Value("${local.server.port}")获得这个端口号,并赋值给port变量。当在Jenkins或其他持续集成服务器上运行测试程序时,这种随机获取端口的能力可以提供测试程序的并行性。
了解完测试类的注解,再看看测试类的内部。由于这是Spring Boot的测试,因此我们可通过@Autowired注解织入任何由Spring管理的对象,或者是通过@Value设置指定的环境变量的值。在现在这个测试类中,我们定义了WebApplicationContext和BookRepository对象。
每个测试用例用@Test注解修饰。在第一个测试用例——contextLoads()方法中,我仅仅需要确认BookRepository连接已经建立,并且数据库中已经包含了对应的测试数据。
第二个测试用例用来测试我们提供的RESTful URL——通过ISBN查询一本书,即“/books/{isbn}”。在这个测试用例中我们使用TestRestTemplate对象发起RESTful请求。
第三个测试用例中展示了如何通过MockMvc对象实现跟第二个测试类似的功能。Spring测试框架提供MockMvc对象,可以在不需要客户端-服务端请求的情况下进行MVC测试,完全在服务端这边就可以执行Controller的请求,跟启动了测试服务器一样。
测试开始之前需要建立测试环境,setup方法被@Before修饰。通过MockMvcBuilders工具,使用WebApplicationContext对象作为参数,创建一个MockMvc对象。
MockMvc对象提供一组工具函数用来执行assert判断,都是针对web请求的判断。这组工具的使用方式是函数的链式调用,允许程序员将多个测试用例链接在一起,并进行多个判断。在这个例子中我们用到下面的一些工具函数:
perform(get(...))建立web请求。在我们的第三个用例中,通过MockMvcRequestBuilder执行GET请求。
andExpect(...)可以在perform(...)函数调用后多次调用,表示对多个条件的判断,这个函数的参数类型是ResultMatcher接口,在MockMvcResultMatchers这这个类中提供了很多返回ResultMatcher接口的工具函数。这个函数使得可以检测同一个web请求的多个方面,包括HTTP响应状态码(response status),响应的内容类型(content type),会话中存放的值,检验重定向、model或者header的内容等等。这里需要通过第三方库json-path检测JSON格式的响应数据:检查json数据包含正确的元素类型和对应的值,例如jsonPath("$.name").value("中文测试")用于检查在根目录下有一个名为name的节点,并且该节点对应的值是“中文测试”。
一个字符乱码问题
2、问题描述:通过spring-boot-starter-data-rest建立的repository,取出的汉字是乱码。
分析:使用postman和httpie验证都没问题,说明是Mockmvc的测试用例写得不对,应该主动设置客户端如何解析HTTP响应,用get.accept方法设置客户端可识别的内容类型,修改后的测试用例如下:
@Test
public void webappPublisherApi() throws Exception {
mockMvc.perform(get("/publishers/1")
.accept(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(content().string(containsString("中文测试")))
.andExpect(jsonPath("$.name").value("中文测试"));
}
SpringBoot应用的集成测试的更多相关文章
- 为什么说JAVA程序员必须掌握SpringBoot?
原文链接:https://w.url.cn/s/AuDahfb SpringBoot 2.0 的推出又激起了一阵学习 SpringBoot 热,那么, SpringBoot 诞生的背景是什么?Spri ...
- 基于spring-boot的应用程序的单元+集成测试方案
目录 概述 概念解析 单元测试和集成测试 Mock和Stub 技术实现 单元测试 测试常规的bean 测试Controller 测试持久层 集成测试 从Controller开始测试 从中间层开始测试 ...
- Mokito 单元测试与 Spring-Boot 集成测试
Mokito 单元测试与 Spring-Boot 集成测试 版本说明 Java:1.8 JUnit:5.x Mokito:3.x H2:1.4.200 spring-boot-starter-test ...
- SpringBoot Test集成测试
1.pom,文件添加相关依赖 如何测试SpringBoot的请求?使用spring-boot-starter-test这个包即可完成测试,SpringBoot项目为什么需要测试本章不作过多说明,重点放 ...
- springboot~集成测试里的redis
测试不应该访问外部资源 对于单元测试,集成测试里,如果被测试的方法中使用到了redis,你需要去模拟一个单机环境的redis server,因为只有这样,你的测试才是客观的,即不会因为网络和其它因素影 ...
- Springboot中对Service层进行集成测试时注意点
@SpringBootTest(classes = {DataSourceAutoConfiguration.class,MybatisAutoConfiguration.class,****Impl ...
- SpringBoot 集成测试
一. 测试一般程序(Service/DAO/Util类) 1. 在pom.xml中引入依赖 2. 生成测试类 <1> 如果使用IntelliJ IDEA,可以使用快捷键直接生成: Wind ...
- springboot(十二):springboot如何测试打包部署
有很多网友会时不时的问我,spring boot项目如何测试,如何部署,在生产中有什么好的部署方案吗?这篇文章就来介绍一下spring boot 如何开发.调试.打包到最后的投产上线. 开发阶段 单元 ...
- springboot(十四):springboot整合shiro-登录认证和权限管理
这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...
随机推荐
- JavaScript中的execCommand
execCommand方法是执行一个对当前文档,当前选择或者给出范围的命令.处理Html数据时常用 如下格式:document.execCommand(sCommand[,交互方式, 动态参数]) , ...
- pdf文件中截取eps图片并压缩
最近遇到了一个问题,需要从pdf裁剪出其中部分的矢量图格式的图片,并保存为eps格式,方便使用. 最简单的方法就是先用acrobat pro将pdf进行页面抽取,并裁剪,剩下所需要的图片部分,然后另存 ...
- VS 2017 开发安卓环境搭建 问题总结
VS 2017可以开发安卓啦,之前一直想尝试开发安卓,但是由于时间忙, Java只学了个基础,不如C#熟练所以一直没有机会接触安卓开发.既然需要利用VS2017开发安卓,那么第一步就是了解VS2017 ...
- spring-mvc 集成 activeMq 常见问题 + 解决方案 (仅供参考)
最近整合 spring-mvc 和 activeMq ,出现了几个异常,我把他记录下来,具体的原理分析我就不太会写了,只把详细情况和解决方案给出来,希望对各位老铁有所帮助! 问题1:缺少log4j的配 ...
- python import自定义模块方法
转自:http://www.cnitblog.com/seeyeah/archive/2009/03/15/55440.html python包含子目录中的模块方法比较简单,关键是能够在sys.pat ...
- webpack4新特性介绍
导语: webpack是一个JS应用打包器, 它将应用中的各个模块打成一个或者多个bundle文件.借助loaders和plugins,它可以改变.压缩和优化各种各样的文件.它的输入是不同的资源,比如 ...
- 最小化安装CentOS7的网卡设置
实验环境:CentOS 7 Minimal Installation 64bit (1511) 最小化安装CentOS 7 后,查看网卡的信息让人很意外,因为网卡的命名规则变了,网卡的名字让人很难懂. ...
- redis配置文件详解及实现主从同步切换
原理:redis复制是怎么进行工作 如果设置了一个slave,不管是在第一次链接还是重新链接master的时候,slave会发送一个同步命令 然后master开始后台保存,收集所有对修改数据的命令.当 ...
- 分析 webpack 打包后的代码
写在前面的:使用的 webpack 版本 3.0.0 一.开始 1. 准备 当前只创建一个文件 index.js,该文件作为入口文件,代码如下. console.log('hello, world') ...
- <经验杂谈>介绍Js简单的递归排列组合
最近在开发SKU模块的时候,遇到这样一个需求,某种商品有N(用未知数N来表示是因为规格的数组由用户制定且随时可以编辑的,所以对程序来说,它是一个未知数)类规格,每一类规格又有M个规格值,各种规格值的组 ...