您好,登錄后才能下訂單哦!
這篇文章給大家介紹Spring Boot中怎么利用JUnit 5實(shí)現(xiàn)單元測(cè)試,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
1. 忽略測(cè)試用例執(zhí)行
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
開(kāi)發(fā)環(huán)境
JDK 8
示例
1.創(chuàng)建 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.工程創(chuàng)建好之后自動(dòng)生成了一個(gè)測(cè)試類。
package tutorial.spring.boot.junit5; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class SpringBootJunit5ApplicationTests { @Test void contextLoads() { } }
這個(gè)測(cè)試類的作用是檢查應(yīng)用程序上下文是否可正常啟動(dòng)。@SpringBootTest 注解告訴 Spring Boot 查找?guī)?@SpringBootApplication 注解的主配置類,并使用該類啟動(dòng) Spring 應(yīng)用程序上下文。Java知音公眾號(hào)內(nèi)回復(fù)“后端面試”, 送你一份Java面試題寶典
4.補(bǔ)充待測(cè)試應(yīng)用邏輯代碼
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 層實(shí)現(xiàn)
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.編寫發(fā)送 HTTP 請(qǐng)求的單元測(cè)試。
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"); } }
說(shuō)明:
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT 使用本地的一個(gè)隨機(jī)端口啟動(dòng)服務(wù);
@LocalServerPort 相當(dāng)于 @Value("${local.server.port}");
在配置了 webEnvironment 后,Spring Boot 會(huì)自動(dòng)提供一個(gè) TestRestTemplate 實(shí)例,可用于發(fā)送 HTTP 請(qǐng)求。
除了使用 TestRestTemplate 實(shí)例發(fā)送 HTTP 請(qǐng)求外,還可以借助 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")); } }
以上測(cè)試方法屬于整體測(cè)試,即將應(yīng)用上下文全都啟動(dòng)起來(lái),還有一種分層測(cè)試方法,譬如僅測(cè)試 Controller 層。
6.分層測(cè)試。
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")); } }
說(shuō)明:
@WebMvcTest 注釋告訴 Spring Boot 僅實(shí)例化 Controller 層,而不去實(shí)例化整體上下文,還可以進(jìn)一步指定僅實(shí)例化 Controller 層的某個(gè)實(shí)例:@WebMvcTest(HelloController.class);
因?yàn)橹粚?shí)例化了 Controller 層,所以依賴的 Service 層實(shí)例需要通過(guò) @MockBean 創(chuàng)建,并通過(guò) Mockito 的方法指定 Mock 出來(lái)的 Service 層實(shí)例在特定情況下方法調(diào)用時(shí)的返回結(jié)果。
關(guān)于Spring Boot中怎么利用JUnit 5實(shí)現(xiàn)單元測(cè)試就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。