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 单元测试示例的更多相关文章

  1. Spring Boot单元测试(Mock)

    Spring Boot单元测试(Mock) Java个人学习心得 2017-08-12 16:07 Mock 单元测试的重要性就不多说了,我这边的工程一般都是Spring Boot+Mybatis(详 ...

  2. IDEA + Spring boot 单元测试

    1. 创建测试类 打开IDEA,在任意类名,任意接口名上,按ctrl+shift+t选择Create New Test image 然后根据提示操作(默认即可),点击确认,就在项目的/test/jav ...

  3. Spring Boot 单元测试详解+实战教程

    Spring Boot 的测试类库 Spring Boot 提供了许多实用工具和注解来帮助测试应用程序,主要包括以下两个模块. spring-boot-test:支持测试的核心内容. spring-b ...

  4. spring boot 单元测试,如何使用profile

    一.问题概述 spring boot项目.单元测试的时候,我发现,总是会使用application.properties的内容,而该文件里,一般是我的开发时候的配置. 比如上图中,dev是开发配置,p ...

  5. Java程序员的日常—— Spring Boot单元测试

    关于Spring boot 之前没有用Spring的时候是用的MockMvc,做接口层的测试,原理上就是加载applicationContext.xml文件,然后模拟启动各种mybatis\连接池等等 ...

  6. 48. spring boot单元测试restfull API【从零开始学Spring Boot】

    回顾并详细说明一下在在之前章节中的中使用的@Controller.@RestController.@RequestMapping注解.如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建 ...

  7. Spring boot 发送邮件示例

    最近的一个项目中用到了邮件发送,所以研究了一下.将其总结下来. 首先 登录邮箱 -->设置-->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务--> ...

  8. spring boot单元测试(转)

    Junit这种老技术,现在又拿出来说,不为别的,某种程度上来说,更是为了要说明它在项目中的重要性.凭本人的感觉和经验来说,在项目中完全按标准都写Junit用例覆盖大部分业务代码的,应该不会超过一半. ...

  9. spring mvc 单元测试示例

    import java.awt.print.Printable; import java.io.IOException; import javax.servlet.http.HttpServletRe ...

随机推荐

  1. idea 使用优化

    1.创建类的模板 /** * Copyright (C), 2015-${YEAR}, XXX有限公司 * FileName: ${NAME} * Author: ${USER} * Date: ${ ...

  2. python 集合创建

  3. RequestMapping中produces属性作用

    注解RequestMapping中produces属性可以设置返回数据的类型以及编码,可以是json或者xml: @RequestMapping(value="/xxx",prod ...

  4. Websocket 简单对话:静态网页与pycharm对话

    WebSocket websocket 是一种在单个Tcp连接上进行双全工通信的协议.websocket通信协议于2011年被IETF定为标准RFC6455,并 由RFc7936补充规范.WebSoc ...

  5. 冒泡排序&直接插入排序&快速排序

    一.冒泡排序 0       1      2      3      4      5 假设有一个6个数的数组,0,1,2,3,4,5是索引,冒泡排序就是相邻两个对比,比如5和4比,如果满足条件就互 ...

  6. Project Euler Problem 5-Smallest multiple

    对每个数字分解素因子,最后对每个素因子去其最大的指数,然后把不同素因子的最大指数次幂相乘,得到的就是最小公倍数 python不熟练,代码比较挫 mp = {} def process(n): i = ...

  7. .net core 文件下载

    public IActionResult Dowanload(string id,int numTypes) { try { var memory = new MemoryStream(): //mo ...

  8. Python--day30--基于tcp协议的套接字socket

    socket 一开始被设计用在一台主机上多个应用程序之间通信. 是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口. 是一个模块,是ip+port,门面模式是一种设计模式. socket通 ...

  9. 模板——BigInteger

    #include <iostream> #include <cstring> #include <string> #include <vector> # ...

  10. 高并发下载tomcat下的文件时,发生java.net.SocketException: Connection reset解决方案

    (1)问题产生:使用500个线程并发下载tomcat工程中的一个文件时,服务器出现java.net.SocketException: Connection reset异常, 客户端出现connect ...