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 ...
随机推荐
- Win7中右下角“小喇叭”声音图标消失的解决方法?(已解决)
Win7中右下角"小喇叭"声音图标消失的解决方法?(已解决) 1.打开任务管理器. 2.右键explorer.exe选择右键结束. 3.在按ctrl+shift+Esc,或者用al ...
- 开发者必知的8款App快速开发工具开发者必知的8款App快速开发工具
"我有一个好创意,就差一个CTO……" "原生APP开发难度大,周期长,成本高,还没上线市场已经被占领了." "APP版本迭代更新,都是企业的一道难关 ...
- 关于 KiCad 画圆弧走线
关于 KiCad 画圆弧走线 有很多关于 关于 KiCad 画圆弧走线的帖子. 最新进展是 V6 在开发中. 但是因为关于 DRC 问题,开发好像有难度. https://bugs.launchpad ...
- LeetCode80 Remove Duplicates from Sorted Array II
题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? (Mediu ...
- 17-2 orm单表操作和多表操作
参考:https://www.cnblogs.com/liwenzhou/p/8660826.html 一 ORM单表操作 1 增删改查 1. 查询 1. 查所有 models.Publisher. ...
- 如何减少idea的内存消耗
如何减少idea的内存消耗 标签: idea 内存 内存泄露 异常 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014028392/articl ...
- include 语句中使用双引号与括号有什么区别?
Include 的语法 你在学习如何构造函数时,看到了不同的 include 语句: # include <iostream> # include "distance.h&quo ...
- [\s\S]*?懒惰模式特殊情形
通常理解[\s\S]*?X (X代表任意指定字符) 表示匹配任何字符的懒惰模式,一旦遇到后面出现的X便停止匹配,但实际不是如此,会尽可能的把后面的内容也匹配进去.如: 表达式 <tr[\s\S] ...
- H3C RARP
- Oracle的dual是什么东西啊
原文:https://zhidao.baidu.com/question/170487574.html?fr=iks&word=dual&ie=gbk Oracle的dual是什么东西 ...