前言
在網站的開發過程中,介面聯調和測試是至關重要的一環,其直接影響產品的核心價值,而目前也有許多技術方案和工具加持,讓我們的開發測試工作更加便捷。介面作為資料傳輸的重要載體,資料格式和內容具有多樣性,從巨集觀的角度上看,分為成功和失敗,這兩種狀態又可以細分,例如失敗對應的狀態碼有5/4,不同的狀態碼代表的問題是不一樣的,都需要一一考慮,成功返回後,所有欄位返回結果又是排列組合形式,那麼問題就來了,是否能在條件容許的情況下快速覆蓋所有的場景呢,從技術的角度上講,問題不大,但是有時候成本卻有點高,那怎麼以一種低成本的方式快速實現呢,本文將圍繞這個問題展開討論,並嘗試提供一種解決方案。
現狀
前面說到了工作中遇到的介面測試場景,當然目前也有很多工具可以幫我們實現介面的測試,如使用廣泛的postman和fiddler等工具,功能強大,可安裝外掛或自定義指令碼,解決資料測試的問題,比如我們想要mock服務,參考https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/ 即可,網上也有很多使用教程,如果願意花些時間的話,一定能給工作帶來效率的提升,好吧,前提是你要花些時間。
api-hook優勢
1.開箱即用
有時候我只想簡單修改一下介面資料,但是需要我安裝軟體,找教程搗騰半天,時間花費了,效率卻降低了,api-hook引入專案中,通過簡單配置(真的很簡單)即可使用,所有操作所見即所得,沒有學習成本;
2.輕量方便
工具足夠輕量,不需要另起服務,不需要單獨維護,它就是你頁面的一部分而已,你可以像控制一個div一樣去控制它;
工具介紹
1.)工具演示
功能說明
【1】是介面攔截/mock的切換區域,【2】可以關閉api-hook工具皮膚,【3】是工具皮膚顯示/隱藏開關;
介面攔截
當工具皮膚可見且處於介面攔截模式下,所有發起ajax請求的介面返回頁面前都會被攔截,當前處於編輯的介面處於介面請求列表第一位置,且背景有斑馬線滾動動畫,如果後續有其他介面響應被捕獲,那麼新的攔截介面處於編輯等待的狀態,背景呈現淡藍色,有底部位移動畫提示。當介面編輯完成,點選【確定】後,處於編輯等待狀態的介面會自動切換成編輯模式,當然也可以自行切換。
介面mock
介面mock整合mockjs的功能,因此template配置可參考mockjs官網說明,這裡需要說明的是template欄位需要遵循JSON格式規範。
2.)環境要求
該工具採用react開發,適用的專案也要求使用react技術框架;此外,工具會攔截所有ajax請求,因此確保你使用的介面請求是通過ajax發出的。
3.)使用方式
安裝npm包
npm install api-hook
元件匯入
在專案入口檔案引入元件
import ApiHook from 'api-hook';
function App() {
return (
<div className="App">
<Main />
<ApiHook
autoFilter
defaultVisiable
allowOrigins={['http://localhost:3000']}
/>
</div>
);
}
......
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>
document.getElementById('root')
);
4.)其他說明
支援響應型別
介面的響應型別目前只支援text/json,因此介面如果是document
,blob
,arraybuffer
等型別,則工具不做處理;
元件引數
屬性 | 說明 | 預設值 |
---|---|---|
autoFilter | 是否預設攔截介面 | false |
defaultVisiable | 工具皮膚是否預設可見 | false |
allowOrigins | 容許開啟工具功能的站點,為陣列型別,只有配置此項,才能在專案中使用工具 |
研發介紹
1.)流程設計
工具提供了兩種模式,介面mock和介面攔截,不同的模式內部流程稍有不同,具體如下:
介面攔截模式下,所有需要被攔截的介面響應都會被api-hook劫持,而不會對請求流程做任何處理。在工具提供的介面上可以修改響應狀態碼和介面的具體內容,在介面mock模式下,就是通過mockjs實現資料的模擬,mockjs通過自定義MockXMLRequest代理所有匹配請求,實現資料的響應。
2.)XMLHttpRequest代理
由於需要修改XMLHttpRequest的預設行為,因此專案程式碼實際訪問的是其代理物件,在介面攔截/mock下,都是重寫XMLHttpRequest物件,具體實現通過ajax-hook和mockjs來實現,接下來我們探究一下其中原理;
ajax-hook
在介面攔截模式,通過ajax-hook提供介面代理XMLHttpRequest原生物件,監聽所有原生xhr物件屬性,確保ajax-hook回撥先執行,其次是ajax請求的回撥;
XMLHttpRequest = function () {
var xhr = new window[realXhr];
for (var attr in xhr) {
var type = "";
try {
type = typeof xhr[attr]
} catch (e) {
}
if (type === "function") {
// hookAjax methods of xhr, such as `open`、`send` ...
this[attr] = hookFunction(attr);
} else {
Object.defineProperty(this, attr, {
get: getterFactory(attr),
set: setterFactory(attr),
enumerable: true
})
}
}
......
}
mockjs
mockjs將原生XMLHttpRequest儲存在window._XMLHttpRequest屬性上,宣告一個MockXMLHttpRequest物件,該物件模擬了XMLHttpRequest的行為和方法,當我們使用Mock.mock(...)api時,執行window.XMLHttpRequest = XHR;這裡XHR就是MockXMLHttpRequest;
代理物件切換
工具在不同模式下,使用不同的代理物件,在切換攔截和mock的時候,需要執行重置原生XMLHttpRequest和初始化代理物件;
// mock模式
registerMock() {
unProxy(); // 解除ajax-hook代理
const { mockList } = this.state;
mockList.forEach(({ url, template }) => {
Mock.mock(url, template); // mock註冊
});
}
// 攔截模式
unRegisterMock() {
if (window._XMLHttpRequest) { // mock代理,重置原生ajax物件
window.XMLHttpRequest = window._XMLHttpRequest;
}
ajaxProxy(); // 啟用ajax-hook代理
}
最後
該工具可供前端開發人員和測試人員使用,力求提供一種更便捷的方式去實現資料的個性化修改。此次只推出了基礎功能,後續還將加入更多新特性,本倉庫地址:https://github.com/lanpangzi-zkg/api-hook ,如果覺得還行就點個star吧,有問題歡迎交流。