天天看點

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

這是 Jerry 2021 年的第 63 篇文章,也是汪子熙公衆号總共第 340 篇原創文章。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹
紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹
紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

Jerry 前一篇文章 基于 OData 模型和 JSON 模型的 SAP UI5 表格控件行項目的添加和删除實作,比較了 SAP UI5 表格控件使用 OData 模型和 JSON 模型的實作差異。

SAP UI5 初學者在學習 OData API 使用時,面臨的一個問題是:如何找到一些公網可以免費使用的 OData 服務。

Northwind 無疑是極佳的選擇之一,但是該服務不支援修改操作。

雖然從理論上講,我們可以使用按照 Jerry 的這篇文章,SAP Cloud Application Programming 介紹(2021 更新版),采用 SAP Cloud Application Programming 模型(CAP),自行在本地搭建一個支援增删改查的 OData 服務,但是對于學習 SAP UI5 的初學者來說,未免有些大材小用。

其實 SAP UI5 自帶了一個很容易使用的 Mock Server,可以用來在本地模拟 OData 服務提供者,響應 SAP UI5 應用發起的 OData 請求,并使用預先配置好的測試資料進行回複。

登入 SAP UI5 官方網站,輸入關鍵字 Mock Server,即可找到其使用文檔:

https://sapui5.hana.ondemand.com/
紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

Mock Server 的運作對于 SAP UI5 應用來說是完全透明的,SAP UI5 應用根本不知道自己發出的請求,到底是被真實的遠端伺服器響應,還是由 Mock Server 傳回。

下面通過實際例子來介紹 Mock Server 的使用步驟。本例全部代碼,在我的 Github 可以獲得:

https://github.com/wangzixi-diablo/ui5-toolset/tree/main/tabledelete/webapp

(1) 在 Table 控制器裡,建立一個 OData 模型執行個體,傳入 OData 服務 url:

/here/goes/your/serviceUrl/

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

該 url 就是我們需要在 Mock Server 裡模拟的 OData 服務位址。

(2) 本地工程檔案裡建立一個 test 檔案夾,其内包含下列三個檔案:

metadata.xml: OData 服務的中繼資料檔案,定義了名為 Products 的 EntitySet,其類型為 Product,後者包含三個字段:

ProductId

Name

Size

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

Products.json

包含了上圖 metadata.xml 檔案裡定義的名為 Products 的 EntitySet 對應的資料。運作時,Mock Server 會自動到其工作目錄查找同名的 .json 檔案,讀取其内容,傳回給 OData 服務的消費者。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

server.js

從 sap/ui/core/util/MockServer 導入 Mock Server 的實作,将步驟一裡 SAP UI5 需要消費的 OData 服務 url,傳入 Mock Server 的 rootUri 屬性即可。

下圖 autoRespondAfter 屬性,定義了使用 Mock Server 響應 OData 請求的延時,即 1 秒後傳回響應。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

三個檔案總共行數加起來不到60行,卻提供了一個功能完整的 Mock Server.

(3) 在該 SAP UI5 應用的 index.html 裡,使用 sap.ui.require 加載本地工程裡的 Mock Server 執行個體,調用其 init 方法,即可啟動該伺服器。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

将 Jerry 的代碼克隆到本地,npm install 之後執行 node local.js:

https://github.com/wangzixi-diablo/ui5-toolset

即可在 Chrome 開發者工具裡觀察 Mock Server 的運作情況:

http://localhost:3002/tabledelete/?sap-ui-debug=true

(1) SAP UI5 表格控件請求 OData 服務的中繼資料。Mock Server 接收到該請求,将工作目錄下的 metadata.xml 的内容,傳回給調用者。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

(2) Jerry 之前的文章 基于 OData 模型和 JSON 模型的 SAP UI5 表格控件行項目的添加和删除實作 曾經提到,OData 模型是伺服器端模型,這意味着表格控件根本不知道目前到底有多少條資料需要顯示。

是以 SAP UI5 表格控件會發送另一條包含 $count 操作的 OData 請求,去查詢 Products 總數。

最終在表格控件裡顯示的條目數,是 $count 操作的結果和 20 兩個數字的較小值。20 是 OData 分頁的預設尺寸,在 Jerry 的文章 SAP UI 搜尋分頁技術 裡有詳細介紹。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

因為我在 Mock Server 的 Products.json 裡隻維護了兩條資料,故 $count 結果為 2.

(3) 現在表格控件已經明确了自己需要顯示兩條資料,故發起第三個 OData 資料請求,KaTeX parse error: Expected 'EOF', got '&' at position 7: skip=0&̲top=2, 向伺服器請求第一頁的前兩條資料。

Mock Server 接收到該請求,将 Products.json 裡全部兩條資料傳回給表格控件。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

(4) 當使用 Add Row 按鈕添加一條新的資料之後,SAP UI5 表格控件依次發送下列三條 OData 請求:

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

删除操作的執行邏輯類似,這裡不再贅述。

SAP UI5 Mock Server 的一些進階用法,可以通過查詢 Mock Server 的幫助文檔來擷取。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

例如,假設我們期望針對 Mock Server 傳回給調用者的資料,進行一些自定義處理。此時可以在 Mock Server 提供的 attachAfter 鈎子函數裡編寫自定義邏輯:

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

如上圖所示,當 Products.json 檔案的資料被 Mock Server 加載,準備傳回給 OData 消費者之前,應用開發人員編寫的 attachAfter 回調函數觸發,将每個産品的 Name 字段值末尾,加上一個句号。

SAP UI5 Mock Server 實際上基于著名的開源 Mock 架構 Sinon.js:

https://github.com/sinonjs/sinon
紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

Sinon 架構的命名,是為了向希臘聯軍與特洛伊人之間長達十年的戰争期間湧現出的英雄戰士 Sinon(西農) 緻敬,就是下圖這位:

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

為了攻破堅固的特洛伊城,希臘聯軍中的奧德修斯想出了“木馬計”:在木馬腹中藏匿士兵,待特洛伊人将木馬拽入城後,等到夜深人靜時,木馬内的士兵一齊湧出,裡應外合,拿下特洛伊城。

Sinon 則勇敢地擔當了誘使特洛伊人将木馬拖進城的艱巨任務。他成功地扮演了一名間諜 (Spy) 的角色,憑借出色的演技使得特洛伊國王堅信,木馬對特洛伊城來說,是個“吉祥物”。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

在基于 Sinon 的 SAP UI5 Mock Server 通過 init 方法啟動時,會調用 Sinon.useFakeXMLHttpRequest,将 Sinon 僞造的 FakeXMLHttpRequest 實作,替換 Window 全局的 XMLHttpRequest, 完成了偷天換日。

這個替換,一般的 SAP UI5 開發人員如果不對 Sinon 源代碼進行單步調試,就不會知情。這個情形有點像昔日希臘聯軍的士兵們,藏匿在特洛伊木馬中,神不知鬼不覺地潛入特洛伊城的場景。

紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹
紀念特洛伊英雄 Sinon - SAP UI5 Mock Server 使用步驟和工作原理介紹

值得一提的是,Sinon 的工作原理,和 Java 以及 Angular 裡的 HTTP Intercept(攔截器)是不同的。在 HTTP 攔截器的工作場景中,HTTP 請求在兩個時間點内,可以被架構或者應用開發人員編寫的攔截器處理:

程式代碼調用 API 發送 HTTP 請求後,在 HTTP 請求實際從浏覽器發出之前,由攔截器進行預處理

應用程式得到遠端的伺服器響應後,在交給其回調函數處理之前,由攔截器進行預處理

攔截器對 HTTP 請求的預處理,其類型包括但不局限于:全局錯誤處理,統一的身份驗證機制,或者增添額外的業務邏輯等等。

而 Sinon 的工作場景下,因為真實的 XMLHttpRequest 已經被 FakeXMLHttpRequest 替換了,是以根本就沒有真實的 HTTP 請求産生,是以 Chrome 開發者工具 network 标簽頁内也就根本觀察不到任何網絡請求。SAP UI5 應用和 Mock Server 之間的互動,純粹是基于 FakeXMLHttpRequest 在記憶體中的一問一答而已。

希望本文能夠幫助大家了解 SAP UI5 Mock Server 的使用步驟,工作原理,以及 Mock Server 背後基于的 Sinon 架構的命名由來。

感謝閱讀。