title: 在 SpringBoot 中使用 JUnit 進行代碼測試
date: 2021-08-24 15:30:00
toc: true
category:
- Java
tags: - Java
- SpringBoot
- 單元
- 測試
Junit 是 Java 知名的測試框架,通過集成 Junit + SpringBoot Test 可以在測試程序中使用 SpringBoot 的依賴注入等 SpringBoot 特性。
依賴#
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
測試 Service#
位置:src/main/java/com/example/service/impl/HelloServiceImpl.java
package com.example.service.impl;
@Service
public class HelloServiceImpl implements HelloService {
@Override
public String helloTo(String name) {
// 故意寫一個 Bug
if ("C++".equals(name))
return "不要對 C++ 打招呼";
return StringUtils.hasText(name) ? "HELLO " + name : "HELLO WORLD";
}
}
想要測試這一段代碼,Java 通用的方式是自己 new
出所需的資源,再進行測試使用,但這樣的話就無法使用 SpringBoot 的各種特性了,如果需要的依賴特別多,或者是牽扯到各種配置讀取的話,簡直就是噩夢:
private HelloService helloService;
@Before
public void setUp() {
helloService = new HelloService();
}
@Test
public void helloTo() {
assertEquals("HELLO WORLD", helloService.helloTo(""));
assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
assertEquals("HELLO C++", helloService.helloTo("C++")); // 出錯
}
方法一:注解啟動 SpringBoot#
位置:src/test/java/com/example/service/impl/HelloServiceImplTest.java
重點:
- 使用 Junit SpringBoot Test 框架:
@RunWith(SpringRunner.class)
- 指定啟動入口:
@SpringBootTest(classes = [SpringBoot 程序入口類])
在測試結束之後,SpringBoot 上下文會自動關閉。
package com.example.service.impl;
import com.example.SpringBootTestApplication;
import com.example.service.HelloService;
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 static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootTestApplication.class)
public class HelloServiceImplTest {
@Autowired
private HelloService helloService;
@Test
public void helloTo() {
assertEquals("HELLO WORLD", helloService.helloTo(""));
assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
assertEquals("HELLO C++", helloService.helloTo("C++")); // 出錯
}
}
方法二:顯式啟動 SpringBoot#
通過使用 SpringApplication::run
方法來啟動 SpringBoot 程序,也可以做到使用 SpringBoot 所有特性來進行測試,但稍微麻煩了些,而且必須在測試結束之後手動對 SpringBootContext
進行關閉。
package com.example.service.impl;
import com.example.SpringBootTestApplication;
import com.example.service.HelloService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import static org.junit.Assert.assertEquals;
public class HelloServiceImplTest2 {
private ConfigurableApplicationContext context;
private HelloService helloService;
@Before
public void setUp() {
context = SpringApplication.run(SpringBootTestApplication.class);
// 顯式獲取 Bean,所需依賴 SpringBoot 會自動注入
helloService = context.getBean(HelloService.class);
}
@After
public void tearDown() {
// 關閉 SpringBoot 程序
context.close();
}
@Test
public void helloTo() {
assertEquals("HELLO WORLD", helloService.helloTo(""));
assertEquals("HELLO WORLD", helloService.helloTo("WORLD"));
assertEquals("HELLO JAVA", helloService.helloTo("JAVA"));
assertEquals("HELLO C++", helloService.helloTo("C++")); // 出錯
}
}