Spring Boot 单元测试示例
Spring 框架提供了一个专门的测试模块(spring-test),用于应用程序的单元测试。 在 Spring Boot 中,你可以通过spring-boot-starter-test启动器快速开启和使用它。
在pom.xml文件中引入maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
1. JUnit单元测试
当你的单元测试代码不需要用到 Spring Boot 功能,而只是一个简单的测试时,你可以直接编写你的 Junit 测试代码:
public class SimpleJunitTest {
@Test
public void testSayHi() {
System.out.println("Hi Junit.");
}
}
2. Spring Boot单元测试
当你的集成测试代码需要用到 Spring Boot 功能时,你可以使用@SpringBootTest注解。该注解是普通的 Spring 项目(非 Spring Boot 项目)中编写集成测试代码所使用的@ContextConfiguration注解的替代品。其作用是用于确定如何装载 Spring 应用程序的上下文资源。
@RunWith(SpringRunner.class)
@SpringBootTest
public class BeanInjectTest {
@Autowired
private HelloService helloService;
@Test
public void testSayHi() {
System.out.println(helloService.sayHi());
}
}
@Service
public class HelloService {
public String sayHi() {
return "--- Hi ---";
}
public String sayHello() {
return "--- Hello ---";
}
}
当运行 Spring Boot 应用程序测试时,它会自动的从当前测试类所在的包起一层一层向上搜索,直到找到一个@SpringBootApplication或@SpringBootConfiguration注释类为止。以此来确定如何装载 Spring 应用程序的上下文资源。
主配置启动类的代码为:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
如果搜索算法搜索不到你项目的主配置文件,将报出异常:
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=…) with your test
解决办法是,按 Spring Boot 的约定重新组织你的代码结构,或者手工指定你要装载的主配置文件:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {YourApplication.class})
public class BeanInjectTest {
// ...
}
基于 Spring 环境的 Junit 集成测试还需要使用@RunWith(SpringJUnit4ClassRunner.class)注解,该注解能够改变 Junit 并让其运行在 Spring 的测试环境,以得到 Spring 测试环境的上下文支持。否则,在 Junit 测试中,Bean 的自动装配等注解将不起作用。但由于 SpringJUnit4ClassRunner 不方便记忆,Spring 4.3 起提供了一个等同于 SpringJUnit4ClassRunner 的类 SpringRunner,因此可以简写成:@RunWith(SpringRunner.class)。
3. Spring MVC 单元测试
当你想对 Spring MVC 控制器编写单元测试代码时,可以使用@WebMvcTest注解。它提供了自配置的 MockMvc,可以不需要完整启动 HTTP 服务器就可以快速测试 MVC 控制器。
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void testHello() throws Exception {
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andDo(print());
}
}
@Controller
public class HelloController {
@GetMapping("/hello")
public String hello(ModelMap model) {
model.put("message", "Hello Page");
return "hello";
}
}
使用@WebMvcTest注解时,只有一部分的 Bean 能够被扫描得到,它们分别是:
@Controller
@ControllerAdvice
@JsonComponent
Filter
WebMvcConfigurer
HandlerMethodArgumentResolver
其他常规的@Component(包括@Service、@Repository等)Bean 则不会被加载到 Spring 测试环境上下文中。
如果测试的 MVC 控制器中需要@ComponentBean 的参与,你可以使用@MockBean注解来协助完成:
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private HelloService helloService;
@Test
public void testSayHi() throws Exception {
// 模拟 HelloService.sayHi() 调用, 返回 "=== Hi ==="
when(helloService.sayHi()).thenReturn("=== Hi ===");
mvc.perform(get("/hello/sayHi"))
.andExpect(status().isOk())
.andDo(print());
}
}
@Controller
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hello/sayHi")
public String sayHi(ModelMap model) {
model.put("message", helloService.sayHi());
return "hello";
}
}
Controller的mock单元测试的另一种方法:
package net.mingsoft.mdiy.action; import net.mingsoft.MSApplication;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebAppConfiguration
@RunWith(SpringRunner.class)
//使用随机端口
@SpringBootTest(classes = {MSApplication.class})// 指定启动类
public class ArticleActionMockTest { @Autowired
private WebApplicationContext wac; private MockMvc mvc; @Before
public void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void testGetMdiyForm() throws Exception{
this.mvc.perform(get("/ms/mdiy/contentModel/form")).andExpect(status().isOk())
.andDo(MockMvcResultHandlers.print()); } }
4. Spring Boot Web 单元测试
当你想启动一个完整的 HTTP 服务器对 Spring Boot 的 Web 应用编写测试代码时,可以使用@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)注解开启一个随机的可用端口。Spring Boot 针对 REST 调用的测试提供了一个 TestRestTemplate 模板,它可以解析链接服务器的相对地址。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ApplicationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testSayHello() {
Map result = restTemplate.getForObject("/hello/sayHello", Map.class);
System.out.println(result.get("message"));
}
}
@Controller
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hello/sayHello")
public @ResponseBody Object helloInfo() {
Map map = new HashMap<>();
map.put("message", helloService.sayHello());
return map;
}
}
Spring Boot 单元测试示例的更多相关文章
- Spring Boot单元测试(Mock)
Spring Boot单元测试(Mock) Java个人学习心得 2017-08-12 16:07 Mock 单元测试的重要性就不多说了,我这边的工程一般都是Spring Boot+Mybatis(详 ...
- IDEA + Spring boot 单元测试
1. 创建测试类 打开IDEA,在任意类名,任意接口名上,按ctrl+shift+t选择Create New Test image 然后根据提示操作(默认即可),点击确认,就在项目的/test/jav ...
- Spring Boot 单元测试详解+实战教程
Spring Boot 的测试类库 Spring Boot 提供了许多实用工具和注解来帮助测试应用程序,主要包括以下两个模块. spring-boot-test:支持测试的核心内容. spring-b ...
- spring boot 单元测试,如何使用profile
一.问题概述 spring boot项目.单元测试的时候,我发现,总是会使用application.properties的内容,而该文件里,一般是我的开发时候的配置. 比如上图中,dev是开发配置,p ...
- Java程序员的日常—— Spring Boot单元测试
关于Spring boot 之前没有用Spring的时候是用的MockMvc,做接口层的测试,原理上就是加载applicationContext.xml文件,然后模拟启动各种mybatis\连接池等等 ...
- 48. spring boot单元测试restfull API【从零开始学Spring Boot】
回顾并详细说明一下在在之前章节中的中使用的@Controller.@RestController.@RequestMapping注解.如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建 ...
- Spring boot 发送邮件示例
最近的一个项目中用到了邮件发送,所以研究了一下.将其总结下来. 首先 登录邮箱 -->设置-->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务--> ...
- spring boot单元测试(转)
Junit这种老技术,现在又拿出来说,不为别的,某种程度上来说,更是为了要说明它在项目中的重要性.凭本人的感觉和经验来说,在项目中完全按标准都写Junit用例覆盖大部分业务代码的,应该不会超过一半. ...
- spring mvc 单元测试示例
import java.awt.print.Printable; import java.io.IOException; import javax.servlet.http.HttpServletRe ...
随机推荐
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- 第四次C++
继承与派生 一.什么是继承和派生 所谓继承就是从先辈处得到属性和行为特征.类的继承,是新的类从已有类那里得到已有的特性.从另一个角度来看这个问题,从已有类产生新类的过程就是类的派生.类的继承与派生机制 ...
- Card Hand Sorting 二进制枚举暴力
这个题其实由于只有4种花色的,那么每种花色排列的顺序,也不过是4!种,然后对于每种花色内部到底是升序还是降序,其实也可以直接暴力,一共也就4!*2^4种情况,然后直接进行排序就可以了,但是我们如何计算 ...
- 洛谷P1807 最长路_NOI导刊2010提高(07)
//拓扑排序求最长路 #include<bits/stdc++.h> #include<queue> using namespace std; const int INF=0x ...
- CNN输出维度的计算
在 CNN 的一层中的 patch 中共享权重 w ,无论猫在图片的哪个位置都可以找到. 当我们试图识别一个猫的图片的时候,我们并不在意猫出现在哪个位置.无论是左上角,右下角,它在你眼里都是一只猫 ...
- 基于TableStore的海量气象格点数据解决方案实战
前言 气象数据是一类典型的大数据,具有数据量大.时效性高.数据种类丰富等特点.气象数据中大量的数据是时空数据,记录了时间和空间范围内各个点的各个物理量的观测量或者模拟量,每天产生的数据量常在几十TB到 ...
- Pytorch的默认初始化分布 nn.Embedding.weight初始化分布
一.nn.Embedding.weight初始化分布 nn.Embedding.weight随机初始化方式是标准正态分布 ,即均值$\mu=0$,方差$\sigma=1$的正态分布. 论据1——查看 ...
- 学习CSS预处理器Less
1.Sass与Less的区别:Sass与Less的区别 2.Less的使用:Less的使用 3.Less的相关网址:Less.js.Less中文网 Less的HSL函数-lighten():HSL函数 ...
- kuangbin专题-连通图A - Network of Schools
这道题的意思是就是 问题 1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校 ...
- apply、call、bind方法调用
---恢复内容开始--- 首先这三个方法的作用都是用来改变this的值,而this的值一般有几种情况. 1.函数作为一个对象的一个方法来调用,此时this的值指向对象. var a={ v:0; f: ...