2021年12月5日 星期日

Spring REST API開發與測試指南:使用Swagger、HATEOAS、JUnit、Mockito、PowerMock、Spring Test

簡介:

鑒於前後端分離與微服務架構的興起,伺服器端需要提供API供使用者存取。傳統的SOAP協定是以複雜的XML作為傳送媒介,已經逐漸被使用輕量化JSON傳送資訊的REST API取代,成為開發與建置API的主流。
除此之外,API的開發和上線應用,效率與品質應該兼顧;透過DevOps流程結合開發、測試、營運,可以更快地將新的或修正的功能發佈給使用者;在這樣的環節中,自動化測試至關重要。
本書第一部分介紹Java的單元測試框架如JUnit5、Mockito、PowerMock,並探討如何提升程式的可測試性。
第二部分先介紹REST API的概念與背景,在使用Spring Boot建置初版REST API後,逐章示範API的例外處理、Swagger文件說明、版本控制、分頁與排序、與套用HATEOAS等。
最後結合Spring Test模組對REST API進行單元測試、整合測試、與端對端測試,以期產出符合企業品質與效率的REST API。

書綱:

<<PART-1>> 建構Java單元測試

CH01: 使用JUnit執行單元測試 (p.41)

1.1. 正式程式碼與測試程式碼的差異

1.2. 單元測試常見名詞說明

1.3. 使用JUnit 5

1.3.1. 簡介JUnit 5

1.3.2. 建立第一個JUnit 5測試專案

1.3.3. 在JUnit 5的架構下執行JUnit 4的測試

1.3.4. 執行JUnit 5的大量測試

1.3.5. 單元測試的生命週期

1.3.6. 使用Assertions

1.3.7. 使用Assumptions

CH02: 建立測試替身 (p.28)

2.1. 執行單元測試

2.1.1. 單元測試的效益

2.1.2. 單元測試的特徵

2.1.3. 單元測試的限制

2.2. 認識測試替身(test doubles)

2.2.1. 測試替身的意義

2.2.2. 測試替身的分類

2.3. 使用Dummy Object

2.3.1. Dummy Object使用情境

2.3.2. Dummy Object使用範例

2.4. 使用Test Stub

2.4.1. Test Stub使用情境

2.4.2. Test Stub使用範例

2.5. 使用Test Spy

2.5.1. Test Spy使用情境

2.5.2. Test Spy使用範例

2.6. 使用Mock Object

2.6.1. Mock Object使用情境

2.6.2. Mock Object使用範例

2.7. 使用Fake Object

2.7.1. Fake Object使用情境

2.7.2. Fake Object使用範例

CH03: 使用Mockito(一) (p.45)

3.1. 認識Mockito

3.1.1. 了解單元測試質量

3.1.2. 設定Maven關聯Mockito

3.2. 章節情境說明

3.3. 使用Mockito驅動單元測試

3.4. 以when()與thenReturn()定義Mock Object的方法

3.5. 以when()與thenThrow()定義Mock Object的方法

3.6. 使用參數配對器(ArgumentMatcher)

3.6.1. 使用類別ArgumentMatchers定義的萬用配對器

3.6.2. 使用介面ArgumentMatcher建立自定義的參數配對器

3.7. 以verify()驗證Mock Object的方法呼叫

3.7.1. 使用Mockito.verify()

3.7.2. 使用Mockito.verifyNoMoreInteractions()

3.7.3. 使用Mockito.verifyNoInteractions()

3.8. 以when()與thenAnswer()定義Mock Object的方法

CH04: 使用Mockito(二) (p.46)

4.1. 章節情境說明

4.2. 快樂路徑與悲傷路徑的測試案例

4.2.1. 測試快樂路徑

4.2.2. 測試悲傷路徑

4.3. 測試void方法

4.3.1. 使用doThrow()

4.3.2. 使用doNothing()

4.3.3. 使用doAnswer()

4.3.4. 使用doCallRealMethod()

4.3.5. 使用連鎖doXXX()

4.4. 使用doReturn()測試有Return的方法

4.5. 使用參數捕捉器(ArgumentCaptor)

4.5.1. 捕捉一般參數

4.5.2. 捕捉使用泛型的集合物件參數

4.5.3. 捕捉陣列參數&可變動個數的參數

4.6. 使用InOrder驗證Mock Object呼叫順序

4.7. 使用Spy Object

4.7.1. 比較Spy Object與Mock Object

4.7.2. 局部偽冒Spy Object

4.7.3. 使用Spy Object驗證SUT內部方法交互作用

4.8. 使用Mockito標註類別

4.8.1. 使用@Captor

4.8.2. 使用@Spy

4.8.3. 使用@InjectMocks

CH05: 使用PowerMock測試legacy程式碼 (p.27)

5.1. 認識legacy程式碼

5.1.2. 測試障礙說明

5.1.3. 簡介PowerMock

5.2. 偽冒static方法

5.3. 抑止類別static成員執行初始化

5.4. 抑止父類別建構子的執行

5.5. 抑止類別建構子的執行

5.6. 抑止方法的執行

5.7. 偽冒private方法

5.8. 偽冒final方法

5.9. 建立final類別的Mock Object

5.10. 使用Mockito偽冒static方法、final方法與類別

5.10.1. 偽冒static方法

5.10.2. 偽冒final方法和類別

CH06: 依據Mockito的可測試性設計程式碼 (p.34)

6.1. 了解測試障礙的可能原因

6.2. 識別建構子的問題

6.2.1. 測試性不良的設計

6.2.2. 以依賴注入提升測試性的設計

6.3. 識別初始化的問題

6.3.1. 測試性不良的設計

6.3.2. 以依賴注入提升測試性的設計

6.4. 識別private方法對單元測試的影響

6.4.1. 測試性不良的設計

6.4.2. 使用關注分離提升測試性的設計

6.4.3. 提升存取層級以提升測試性

6.5. 識別static方法對單元測試的影響

6.5.1. 測試性不良的設計

6.5.2. 以非static的方法重構

6.5.3. 啟用Mockito偽冒static的支援

6.6. 識別final方法對單元測試的影響

6.6.1. 測試性不良的設計

6.6.2. 以非final的方法重構

6.7. 識別final類別對單元測試的影響

6.7.1. 測試性不良的設計

6.7.2. 以建立final類別的介面執行重構

6.8. 識別使用new呼叫建構子造成的測試問題

6.8.1. 測試性不良的設計

6.8.2. 以依賴注入提升測試性的設計

6.9. 識別使用static變數和程式碼區塊造成的測試問題

6.9.1. 測試性不良的設計

<<PART-2>> 建構Spring REST API

CH07: 簡介REST (p.17)

7.1. 什麼是REST?

7.2. 認識資源(Resources)

7.2.1. 辨識資源

7.2.2. URI模板(Templates)

7.3. 資源呈現(Representation)

7.4. HTTP方法

7.4.1. GET方法

7.4.2. HEAD方法

7.4.3. DELETE方法

7.4.4. PUT方法

7.4.5. POST方法

7.4.6. PATCH方法

7.4.7. CRUD 和 HTTP 動詞

7.5. HTTP狀態碼

7.6. 理查森的成熟度模型

CH08: 建構REST API專案 (p.40)

8.1. 介紹QuickPoll(快速投票)範例專案

8.2. 設計QuickPoll專案

8.2.1 資源識別

8.2.2 資源呈現(Representation)

8.2.3 端點(Endpoint)識別

8.2.4 HTTP方法識別

8.3. QuickPoll專案架構說明

8.4. 實作QuickPoll專案

8.4.1 建置Spring Boot專案

8.4.2 實作Domain物件

8.4.3 實作Repository

8.4.4 介紹API測試工具Talend API Test 

8.4.5 實作REST API

CH09: REST API的例外處理 (p.22)

9.1. 資源不存在的例外處理

9.1.1 資源不存在應回應404狀態碼

9.1.2 客製化回應資訊

9.2. 請求參數異常的例外處理

9.2.1 以JSR-303與JSR-349驗證請求參數

9.2.2 客製化回應資訊與參數驗證提示

9.3. 請求JSON格式異常的例外處理

CH10: 建立REST API使用文件 (p.32)

10.1. 簡介Swagger

10.2. 使用swagger-springmvc套件整合Swagger

10.3. 簡介Swagger UI

10.4. 客製Swagger UI的資源列表文件

10.4.1 Swagger UI需要調整的地方

10.4.2 客製Swagger UI的方式

10.5. 客製Swagger UI的API宣告文件

10.5.1 使用@Api客製群組端點概述

10.5.2 使用@ApiOperation客製端點操作敘述

10.5.3 使用@ApiResponse客製端點回應描述

10.6. 客製Swagger UI其他頁面呈現

10.7. 使用springfox-swagger2與springfox-swagger-ui套件整合Swagger

10.7.1 設定pom.xml

10.7.2 設定SwaggerConfig.java

CH11: REST API的版本控制、分頁與排序 (p.26)

11.1. 對API執行版本控制 (Versioning)

11.1.1 版本控制策略介紹

11.1.2 為範例專案套用版本控制

11.1.3 設定Swagger提供版本控制說明

11.2. 對API的回應內容分頁 (Pagination)

11.2.1 分頁策略介紹

11.2.2 為範例專案套用分頁機制

11.2.3 修改分頁預設資料筆數

11.3. 對API的回應內容排序 (Sorting)

11.3.1 升冪排序或降冪排序

11.3.2 為範例專案套用排序機制

CH12: 套用HATEOAS (p.20)

12.1. 簡介HATEOAS與HAL

12.1.1 簡介HATEOAS

12.1.2 簡介HAL

12.2. 為範例專案套用Spring HATEOAS

12.2.1 簡介Spring HATEOAS

12.2.2 整合HATEOAS與未分頁回應

12.2.3 整合HATEOAS與分頁回應

<<PART-3>> 測試Spring REST API

CH13: 存取與測試REST API (p.52)

13.1. 軟體的端對端測試、整合測試、單元測試

13.2. REST API的端對端測試

13.2.1. 使用JDK函式庫與RestTemplate存取資源端點

13.2.2. 使用RestTemplate的POST相關方法新增資源

13.2.3. 使用RestTemplate的GET相關方法查詢資源

13.2.4. 使用RestTemplate的PUT與PATCH相關方法更新資源

13.2.5. 使用RestTemplate的DELETE相關方法刪除資源

13.2.6. 使用RestTemplate的GET相關方法查詢分頁資源

13.3. REST API的單元測試

13.3.1. 測試Rest Controller的POJO功能性

13.3.2. 測試Rest Controller的Controller功能性

13.4. REST API的整合測試

沒有留言:

張貼留言