一、springboot2 中的 Junit5 使用
对于service层测试,Junit5中只需要@SpringBootTest即可,不需要额外Mockmvc
Springboot 整合 Junit 以后
编写测试方法:@Test标注(注意需要使用 junit5 版本的注解)
Junit类具有 Spring 的功能, 例如 @Autowired、@Transactional (标注测试方法,测试完成后自动回)
我们只需要引入 spring-boot-starter-test 依赖即可完成整合,其它的 Springboot 底层都已经帮我们自动配置好了
使用最新的springboot的版本, 使用的是junit5版本, 现在很多都是使用junit4的测试, 这里使用Junit5来试验. junit4和junit5两个版本差别比较大。

junit5基于java8写的,要求最低版本为java8。
预言使用:
Assertions.assertEquals("index", result);
使用ideal构建springboot项目,pom.xml(部分) 如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--加入下面的引入,可以使用junit5的版本来测试; 如果想用junit4的测试, 把exclusioins去除-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
建立一个controller
package com.test.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/index")
public class IndexController {
private static final Logger LOG = LoggerFactory.getLogger(IndexController.class);
@RequestMapping(value="/getData")
@ResponseBody
public String getData(@RequestParam(value="searchPhrase", required=false) String searchPhrase) {
String status = "{\"status\" : \"200\", \"searchPhrase\" : \"" + searchPhrase + "\"}";
return status;
}
}
建立一个测试类:
package com.test.demo;
import com.test.demo.controller.IndexController;
import org.junit.jupiter.api.*; //注意这里, 这是junit5引入的; junit4引入的是org.junit.Test这样类似的包
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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
//这里只写SpringBootTest这个注解; 如果是junit4的话, 就要加上@RunWith(SpringRunner.class)
@SpringBootTest
class DemoApplicationTests {
private static final Logger LOG = LoggerFactory.getLogger(DemoApplicationTests.class);
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Test
void contextLoads() {
}
@BeforeAll
public static void beforeAll(){
LOG.info("beforeAll");
}
@BeforeEach
public void beforeEach(){
LOG.info("beforeEach"); //mockMvc = MockMvcBuilders.standaloneSetup(new IndexController()).build();
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@AfterEach
public void afterEach(){
LOG.info("afterEach");
}
@AfterAll
public static void afterAll(){
LOG.info("afterAll");
}
@Test
public void testTwo() throws Exception {
RequestBuilder request = MockMvcRequestBuilders.get("/index/getData")
.param("searchPhrase","ABC") //传参
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON); //请求类型 JSON
MvcResult mvcResult = mockMvc.perform(request)
.andExpect(MockMvcResultMatchers.status().isOk()) //期望的结果状态 200
.andDo(MockMvcResultHandlers.print()) //添加ResultHandler结果处理器,比如调试时 打印结果(print方法)到控制台
.andReturn(); //返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;
int status = mvcResult.getResponse().getStatus(); //得到返回代码
String content = mvcResult.getResponse().getContentAsString(); //得到返回结果
LOG.info("status:" + status + ",content:" + content);
}
}
最后进行测试:
进入自己的目录, 这里我是通过命令运行的, 也可以通过其他方式运行(如ide的环境)
cd xxx/Demo>mvn test
测试结果如下:
2020-04-11 13:04:49.920 [main] INFO com.test.demo.DemoApplicationTests - beforeAll 2020-04-11 13:04:55.239 [main] com.test.demo.DemoApplicationTests: beforeEach MockHttpServletRequest: HTTP Method = GET Request URI = /index/getData Parameters = {searchPhrase=[ABC]} Headers = [Content-Type:"application/json", Accept:"application/json"] Body = <no character encoding set> Session Attrs = {} Handler: Type = com.test.demo.controller.IndexController Method = com.test.demo.controller.IndexController#getData(String) Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 200 Error message = null Headers = [Content-Type:"application/json", Content-Length:"42"] Content type = application/json Body = {"status" : "200", "searchPhrase" : "ABC"} Forwarded URL = null Redirected URL = null Cookies = [] 2020-04-11 13:04:55.395 INFO 13164 --- [main] com.test.demo.DemoApplicationTests: status:200,content:{"status" : "200", "searchPhrase" : "ABC"}
2020-04-11 13:04:56.002 INFO 13164 --- [main] com.test.demo.DemoApplicationTests: afterEach
2020-04-11 13:04:56.009 INFO 13164 --- [main] com.test.demo.DemoApplicationTests: afterAll
这里可以看到返回的结果status:200,content:{"status" : "200", "searchPhrase" : "ABC"}
其中传入的参数是ABC!!!