需求背景
1. 可以进行自动化测试,配合CI,在项目发布前可以验证功能
2. 尽可能早发现问题,及时修复解决
技术点
主要使用了两个注解
1. @RunWith
2. @SpringBootTest
案例说明
场景案例分析:
1. 普通Java测试,比如配置参数加载,静态方法返回值等
2. 普通Web接口测试
3. 业务服务层代码测试
4. 使用MockMvc测试接口
代码演示
举两个例子
1. 普通Web接口测试
package com.md.demo;
import java.net.URL;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import junit.framework.TestCase;
/**
* 普通Web接口测试
*
* @author Minbo
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) // 指定启动类和随机端口
public class ApplicationWebApiTest {
protected static Logger logger = LoggerFactory.getLogger(ApplicationWebApiTest.class);
/**
* @LocalServerPort 提供了 @Value("${local.server.port}") 的代替
*/
@LocalServerPort
private int port;
private URL base;
@Autowired
private TestRestTemplate restTemplate;
@Before
public void setUp() throws Exception {
String url = String.format("http://localhost:%d/", port);
logger.info("随机自动分配端口后的整体请求头--->>> " + url);
this.base = new URL(url);
}
/**
* 向"/hello"地址发送请求,并打印返回结果
*
* @throws Exception
*/
@Test
public void testUrlApi() throws Exception {
String url = this.base.toString() + "/hello";
logger.info("待测试接口地址:url=" + url);
ResponseEntity<String> response = this.restTemplate.getForEntity(url, String.class, "");
String result = response.getBody();
logger.info("返回结果:result=" + result);
boolean expected = false;
if (result != null && result.contains("sprint-boot2-autotest")) {
expected = true;
}
TestCase.assertEquals(true, expected);
}
}
2. 使用MockMvc测试接口
package com.md.demo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
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.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/**
* 使用MockMvc测试接口
*
* @author Minbo
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class) // 指定启动类
@AutoConfigureMockMvc // 测试接口用
@WebAppConfiguration
public class ApplicationMockTest {
protected static Logger logger = LoggerFactory.getLogger(ApplicationMockTest.class);
@Autowired
private MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@Before
public void setupMockMvc() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Before
public void testBefore() {
logger.info("测试前,打印...");
}
@After
public void testAfter() {
logger.info("测试后,打印...");
}
@Test
public void apiTest() throws Exception {
String url = "/hello";
String expectResult = "Hello,greetings from sprint-boot2-autotest";
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(url))
// 期望:200成功状态码
.andExpect(MockMvcResultMatchers.status().isOk())
// 期望:返回结果数据
.andExpect(MockMvcResultMatchers.content().string(expectResult)).andReturn();
int status = mvcResult.getResponse().getStatus();
logger.info("返回状态码status=" + status);
String content = mvcResult.getResponse().getContentAsString();
logger.info("返回结果数据content=" + content);
}
}
注解说明
@SpringBootTest注解底层实际上还是使用了Junit框架
Junit基本注解介绍
@BeforeClass 在所有测试方法前执行一次,一般在其中写上整体初始化的代码
@AfterClass 在所有测试方法后执行一次,一般在其中写上销毁和释放资源的代码
@Before 在每个测试方法前执行,一般用来初始化方法
@After 在每个测试方法后执行,在方法执行完成后要做的事情
@Test(timeout = 1000) 测试方法执行超过1000毫秒后算超时,测试将失败
@Test(expected = Exception.class) 测试方法期望得到的异常类,如果方法执行没有抛出指定的异常,则测试失败
@Test 编写一般测试用例
完整源码下载
https://github.com/hemin1003/spring-boot-study/tree/master/spring-boot2-study/spring-boot2-parent
参考资料
1. https://blog.csdn.net/qq_39508544/article/details/78461020
2. https://blog.csdn.net/fxbin123/article/details/80617754
3. https://www.cnblogs.com/Mblood/p/9699341.html
下一章教程
SpringBoot从入门到精通教程(二)- 拦截器用法和场景案例分析
该系列教程
------------------------------------------------------
------------------------------------------------------
关于我(个人域名)
期望和大家一起学习,共同进步,共勉,O(∩_∩)O谢谢
欢迎交流问题,可加个人QQ 469580884,
或者,加我的群号 751925591,一起探讨交流问题
不讲虚的,只做实干家
Talk is cheap,show me the code
如果觉得内容赞,您可以请我喝杯咖啡: