
你有過這種經驗嗎?明明只改了一行看似無關緊要的代碼,結果上線後,接到系統崩潰的電話,翻遍整個專案才發現問題只是刪了不該刪除的判斷!
不聊深奧的架構,我們來手把手建立起那道讓晚上能安心睡覺的"第一道代碼防護網"!
此篇我們可以學到 :
為何要寫 Unit Test :
省錢(早期糾錯): 在開發階段修 Bug 只要幾分鐘;上線後修 Bug 可能要因為此錯誤需修正資料、排除後續異常,動員整個團隊處理 (筆者還曾經在會計人員旁罰站~^^ )。
省心(重構保障): 當我們修改舊程式碼時,測試就像「防護網」,一鍵通知是否不小心弄壞了別的功能。
省力(活的文件): 測試案例直接示範了程式碼「該如何運作」,比任何過時的開發文件都更可靠,也有現行參數可以測試使用。
寫出屬於自己專案的 Unit Test
下列為我們案例會使用的程式碼
GitHub : https://github.com/KuangHung/java.git
IDE : IntelliJ IDEA Community Edition
JDK : Oracle Open Jdk 21.0.3
首先,Unit Test 使用的套將維護在 pom.xml 中
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
IDE 的 JDK 可由此路徑確認

確定好環境後,我們就可以開始撰寫第一段程式碼,下列程式碼為取得 Cookie 的資料,並且印出 Cookie 的 User Name 案例
@GetMapping("/getCookie")
public String getCookie(HttpServletRequest request) {
String username = "";
System.out.println("getCookie");
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName());
if ("username".equals(cookie.getName())) {
username = cookie.getValue();
// 在這裡處理 Cookie 的值
break;
}
}
}
System.out.println("getCookie username : "+username);
return username;
}
通常,如果此段程式碼會做為 API 使用,因此我們需要透過第三方工具如 Postman 或真正啟動一個網頁前端,才能打到後端 API ,費時又費力。
此時我們可以考慮直接寫一個對應的 Unit Test 來直接測試程式,案例程式如下 :
藍框為被測試的程式,紅框為測試的 Unit Test
// 為需要被測試的該支程式,我們會需要設定,此設定將模擬的 Mock 物件注入到測試目標
@InjectMocks
private HelloController helloController;
// 用來模擬被測試的程式中,所有伺服器的請求
@Mock
private HttpServletRequest request;
// 執行Unit Test ,初始化所有的 Mock
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
/**
* 測試用途:驗證 Controller 是否能正確從 Cookie 中提取 username
*/
@Test
public void getCookie_Test() {
String username = "john_doe";
// 1. 建立一個模擬的 Request 物件
request = Mockito.mock(HttpServletRequest.class);
// 2. 定義行為:當呼叫 getCookies() 時,回傳內含指定 username 的 Cookie 陣列
Cookie[] cookies = {new Cookie("username", username)};
Mockito.when(request.getCookies()).thenReturn(cookies);
// 3. 執行測試目標方法
String result = helloController.getCookie(request);
// 4. 驗證:結果不應為空,且必須等於預期的內容
Assert.assertNotNull(result);
Assert.assertEquals(username, result);
}
執行第一次測試 :
將可以看到測試後,被測試的程式碼會有顏色標註,綠色代表此次測試有涵蓋,紅色則代表此次測試沒有執行到的部分。

測試結果符合預期,將顯示率勾勾。
此時,我們執行完第一個案例,並且這個 Unit Test 案例執行為 Pass,接下來逐步解說我們如何完成測試的部分 :

接下來我們來假設,程式改錯了,所以應該要觸發 Unit Test測試失敗
可以看到,行 44 的 username 在無意中新增了一個 _ ,此時去執行 Unit Test,將會顯示失敗。
可以看到,我們的Unit Test 示警,並且提示應該回傳的正確資料,與實際回傳的資料差異,藉此我們可以透過這個問題去回追程式哪邊有問題。
總結 :
感謝你花時間看完了這篇分享。建立防護網的過程雖然需要多花心思,但這絕對是讓我們從『忙著救火』轉向『穩定開發』最值得的投資 。
希望這篇文章能讓你少走一點彎路,早點寫完程式、安心下班。如果在實作 Unit Test 遇到任何困難,或是也曾有過那種『在會計人員旁罰站』的慘痛回憶 ,歡迎在下方留言跟我分享,我們一起避坑!
其他的學習文章