昨日封裝了JWT的實作邏輯,最後使用Junit對JWT模組的創建Token與解析Token方法,這種針對單一模組進行的測試稱為單元測試,並且在驗證輸出結果時,會根據輸出值進行驗證,這種執行測試的方式稱為Mock,目的是為了模擬真實環境,並撰寫相應邏輯確保實際行為符合期望
撰寫測試的目的就是為了減少BUG產生,因此實作測試時,會依實際目的思考幾個情境:
正常操作的情境: 確認資料或相關操作(資料庫異動),如預期執行
輸入錯誤的情境: 驗證是否如預期拋出異常,或回傳錯誤訊息
除了針對單一模組進行測試外,Spring Boot提供了MockMvc的API,讓開發者可以對Spring MVC撰寫測試案例,模擬實際發送請求的情況進行測試,測試方式能對特定端點,發送不同Http請求,並透過Moke元件對回傳的資料,和響應狀態碼進行驗證,現在來針對JWT驗證跟授權的API進行測試
先在測試資料夾下建立新的測試 ApiTest.java
@SpringBootTest
@ActiveProfiles("test")
public class ApiTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@BeforeEach
public void setup() {
// 將 mockMvc 在webApplicationContext環境中執行
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
...其他內容
}
測試 授權 Token API是否正確
/**
* 測試初始化 Token API內容是否正常運作
* @throws Exception
*/
@Test
public void checkGenerateJwtOk() throws Exception {
mockMvc.perform(MockMvcRequestBuilders
.get("/api/jwt/generate"))
.andExpect(MockMvcResultMatchers.status().isOk())
// 確認有沒有回傳 token欄位
.andExpect(MockMvcResultMatchers.jsonPath("$.token").exists());
}
測試Token 驗證 API
// 先補上驗證Token API實作方法
@GetMapping("/jwt/auth")
public Map<String, Object> authJwt(
@RequestHeader Map<String, String> headers
) {
String clientToken = headers.get("authorization");
Claims data = jwtUtil.parseToken(clientToken);
String sub = data.get("sub", String.class);
Boolean status = sub instanceof String;
Map<String, Object> response = new HashMap<>();
response.put("status", status);
response.put("sub", sub);
return response;
}
/**
* 測試認證Token API
*
* @throws Exception
*/
@Test
public void checkAuthToken() throws Exception {
String checkValue = "王小明";
String headerToekn = jwtUtil.generateToken(null, checkValue);
mockMvc.perform(
MockMvcRequestBuilders
.get("/api/jwt/auth")
.header("authorization", headerToekn)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
// 正常情況 status 回傳 true
.andExpect(MockMvcResultMatchers.jsonPath("$.status").value(true))
// 實際 sub 要與 Token內的 sub 相同
.andExpect(MockMvcResultMatchers.jsonPath("$.sub").value(checkValue));
}
今天介紹了透過Mock執行Http呼叫API並驗證回傳結果,下一篇會講解安全性驗證神器Spring Security的使用方式