這篇文章給大家介紹Spring Boot中怎么利用JUnit 5實現單元測試,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
1. 忽略測試用例執行
JUnit 4:
@Test @Ignore public void testMethod() { // ... }
JUnit 5:
@Test @Disabled("explanation") public void testMethod() { // ... }
2. RunWith 配置
JUnit 4:
@RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { @Test public void contextLoads() { } }
JUnit 5:
@ExtendWith(SpringExtension.class) @SpringBootTest public class ApplicationTests { @Test public void contextLoads() { } }
3. @Before、@BeforeClass、@After、@AfterClass 被替換
@BeforeEach 替換 @Before
@BeforeAll 替換 @BeforeClass
@AfterEach 替換 @After
@AfterAll 替換 @AfterClass
開發環境
JDK 8
示例
1.創建 Spring Boot 工程。
2.添加 spring-boot-starter-web 依賴,最終 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/> </parent> <groupId>tutorial.spring.boot</groupId> <artifactId>spring-boot-junit5</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-junit5</name> <description>Demo project for Spring Boot Unit Test with JUnit 5</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.工程創建好之后自動生成了一個測試類。
package tutorial.spring.boot.junit5; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class SpringBootJunit5ApplicationTests { @Test void contextLoads() { } }
這個測試類的作用是檢查應用程序上下文是否可正常啟動。@SpringBootTest 注解告訴 Spring Boot 查找帶 @SpringBootApplication 注解的主配置類,并使用該類啟動 Spring 應用程序上下文。Java知音公眾號內回復“后端面試”, 送你一份Java面試題寶典
4.補充待測試應用邏輯代碼
4.1. 定義 Service 層接口
package tutorial.spring.boot.junit5.service; public interface HelloService { String hello(String name); }
4.2. 定義 Controller 層
package tutorial.spring.boot.junit5.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import tutorial.spring.boot.junit5.service.HelloService; @RestController public class HelloController { private final HelloService helloService; public HelloController(HelloService helloService) { this.helloService = helloService; } @GetMapping("/hello/{name}") public String hello(@PathVariable("name") String name) { return helloService.hello(name); } }
4.3. 定義 Service 層實現
package tutorial.spring.boot.junit5.service.impl; import org.springframework.stereotype.Service; import tutorial.spring.boot.junit5.service.HelloService; @Service public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { return "Hello, " + name; } }
5.編寫發送 HTTP 請求的單元測試。
package tutorial.spring.boot.junit5; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; 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; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HttpRequestTest { @LocalServerPort private int port; @Autowired private TestRestTemplate restTemplate; @Test public void testHello() { String requestResult = this.restTemplate.getForObject("http://127.0.0.1:" + port + "/hello/spring", String.class); Assertions.assertThat(requestResult).contains("Hello, spring"); } }
說明:
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT 使用本地的一個隨機端口啟動服務;
@LocalServerPort 相當于 @Value("${local.server.port}");
在配置了 webEnvironment 后,Spring Boot 會自動提供一個 TestRestTemplate 實例,可用于發送 HTTP 請求。
除了使用 TestRestTemplate 實例發送 HTTP 請求外,還可以借助 org.springframework.test.web.servlet.MockMvc 完成類似功能,代碼如下:
package tutorial.spring.boot.junit5.controller; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; 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.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; @SpringBootTest @AutoConfigureMockMvc public class HelloControllerTest { @Autowired private HelloController helloController; @Autowired private MockMvc mockMvc; @Test public void testNotNull() { Assertions.assertThat(helloController).isNotNull(); } @Test public void testHello() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.get("/hello/spring")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("Hello, spring")); } }
以上測試方法屬于整體測試,即將應用上下文全都啟動起來,還有一種分層測試方法,譬如僅測試 Controller 層。
6.分層測試。
package tutorial.spring.boot.junit5.controller; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; 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 tutorial.spring.boot.junit5.service.HelloService; @WebMvcTest public class HelloControllerTest { @Autowired private HelloController helloController; @Autowired private MockMvc mockMvc; @MockBean private HelloService helloService; @Test public void testNotNull() { Assertions.assertThat(helloController).isNotNull(); } @Test public void testHello() throws Exception { Mockito.when(helloService.hello(Mockito.anyString())).thenReturn("Mock hello"); this.mockMvc.perform(MockMvcRequestBuilders.get("/hello/spring")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("Mock hello")); } }
說明:
@WebMvcTest 注釋告訴 Spring Boot 僅實例化 Controller 層,而不去實例化整體上下文,還可以進一步指定僅實例化 Controller 層的某個實例:@WebMvcTest(HelloController.class);
因為只實例化了 Controller 層,所以依賴的 Service 層實例需要通過 @MockBean 創建,并通過 Mockito 的方法指定 Mock 出來的 Service 層實例在特定情況下方法調用時的返回結果。
關于Spring Boot中怎么利用JUnit 5實現單元測試就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。