Mock 能做什麼?
1.API 沒開發好,使用 Mock 快速對接
在產品經理髮布需求後,前後端同學先根據功能需求出一份 API 文檔,然後再按照 API 文檔並行開發。
不依賴後端提供數據的情況下,如何讓前端獨立於後端進行開發呢?
使用 Mock,你可以在開發環境代碼內置 Mock,攔截請求,模擬真實 API 返回。如果公司使用了接口管理平台,文檔發佈的時候可以還通過平台生成 Mock API 直接對接。
2.為測試提供數據
使用Mock 假數據替代我們想控制但控制困難的部分
例如
- 某些 API 依賴其他 API 的返回值,使用 Mock 方便的對返回值進行改變,測試不同場景下 API 的表現。
- 某個 API 特別慢,可以暫時用 Mock 代替它,快速調通整個場景測試流程。
3.方便快速建立功能原型
敏捷開發過程中,調整需求是很常見的。通過 Mock 可以快速建立功能原型,直觀的看到業務邏輯,方便產品調整需求,還可以使用假數據對系統進行演示。
Mock 部署
記錄以下三種方案,各有千秋。
1.將 Mock 寫到代碼變量中,哪裏需要寫哪裏
例如
優點
- 成本低,使用簡單,只需要學習 Mock.js 模板語法。
- 不受網絡影響。
- 改動 Mock 能夠快速看到效果。
缺點
- Mock 代碼與業務代碼耦合高,上線容易遺漏測試代碼,為代碼偷偷埋下一顆地雷。
- 無法快速響應文檔改動,保持 Mock 返回數據與文檔一致。
- 只有前端開發人員能用到 Mock,無法與其他部門人員協同工作。
- 沒有 API 請求,不夠真實。
2. Mock.js 攔截請求
使用 Mock.mock 函數攔截請求
var data = Mock.mock("https://www.baidu.com", {
"string|1-10": "★", //隨機生成 1-10 個字符串"★"
})
var request = new XMLHttpRequest();
request.open("GET", "https://www.baidu.com", true);
request.send();
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
console.log(request.responseText)
}
}
控制枱輸出
優點
- 成本低,使用簡單,學習 Mock.js 模板語法、 Mock.mock 函數。
- 不受網絡影響。
- 改動 Mock 能夠快速看到效果。
缺點
- 對於 RESTful 風格的 API,需要寫正則匹配請求地址。
- Mock 代碼與業務代碼仍存在耦合,可以獨立一個 Mock 文件夾,上線構建時不打包進業務代碼。
- 無法快速響應文檔改動,保持 Mock返回數據與文檔一致;
- API 請求被 Mock 攔截,沒有實際發送,不夠真實。
- 只有前端開發人員能用到 Mock,無法與其他部門人員協同工作。
3. Mock Server
和實際請求 HTTP API 沒有區別,API 的響應值不是真實從數據庫獲取的數據,而是 Mock 生成的假數據。
一般是後端人員維護 Mock Server,他們改動 API 的時候同步改動 mock,前端不用考慮 Mock,只需要變更請求地址。
優點
- 維護文檔的人員可以維護 Mock,文檔改動同時改動 Mock,響應迅速!
- 協同方便,測試人員可以利用開發建立的 Mock 提前建立單元測試。
- 使用工具的話可以通過用户界面管理 Mock 數據。
缺點
- 需要花錢(部署服務器的錢或者 Sass 付費)
- 需要選擇靠譜的工具,否則使用工具的提高的效率跟不上你幫工具找 Bug 的速率
- 額外管理 Mock Server,前端無法快速改變 Mock 值。
自己搭建
針對各種語言的部署方案教程豐富,例子不舉了,自個兒搜。
平台部署
Eolinker
在線網站,無需部署。免費版本支持 3 人協作,超過 3 人需要開通付費版。
可以管理 API 文檔,系統提供的 Mock 功能通過 API 文檔返回值信息快速生成隨機數據。支持設置觸發條件(請求頭、請求體),根據不同的觸發條件得到不同的返回值。
Easy Mock
沒使用過,支持在線(在線版本可能不夠穩定),也支持本地部署。
Mock 數據生成規範
可以通過兩種方式告訴 Mock 如何生成數據,一種是自定義規則的數據模板,一種是佔位符,提供一些常見的隨機值,例如·圖片、郵箱、人名等。
1.數據模板定義規範(Data Template Definition,DTD)
先看一個示例,Mock.mock 函數根據相應的數據模板生成相應 JSON。
Mock.mock({
"string|1-10": "★",//隨機生成 1-10 個字符串"★"
"string2|3": "★",//固定生成 3 個字符串"★"
"number|+1": 202,//每次請求自增 1,初始值為 202
"number2|1-100.1-10": 1,//生成一個浮點數,整數部分1-100,小數部分保留1-10 位。。
"boolean|1-2": true,//值為 true 的概率是 1/(1+2),值為 false 的概率同樣是 2/3。
"regexp": /[a-z][A-Z][0-9]/,//隨機生成滿足正則的字符串
"object|2": {
"310000": "上海市",
"320000": "江蘇省",
"440000":"廣東省"
},//對象中隨機選取 2 個屬性,生成對象
"array|1": [ "AMD","CMD"],//數組中隨機選取 1 個元素,最終生成值
"arrayRepeat|3": ["AMD","CMD"],//重複數組元素 3 次,最終生成數組
"date":"@date"//生成隨機日期
})
生成結果
{
"string": "★★",
"string2": "★★★",
"number": 202,
"number2": 71.73566,
"boolean":true,
"regexp": "qS8",
"absolutePath": "★★ demo",
"object": {
"310000": "上海市",
"440000": "廣東省"
},
"array": "AMD",
"arrayRepeat": ["AMD","CMD", "AMD","CMD",AMD","CMD"],
"date":"1980-12-19"
}
數據模板中的每個屬性由 3 部分構成:屬性名、生成規則、屬性值:
// '屬性名|生成規則':屬性值
'name|rule': value
針對不同的屬性值,生成規則的意義也不一樣,有的生成規則是概率(Boolean),有的生成規則是重複。具體的意義可以查閲 Mock.js 官方文檔
2.數據佔位符定義規範(Data Placeholder Definition,DPD)
佔位符是 mock 提供一些常用的隨機數據例如隨機生成的圖片、郵箱、人名等。
用法1: 直接使用
Mock.mock('@date')//1982-10-15
Mock.Random.date()//1997-12-31
用法2: 在數據模板中使用
Mock.mock({
"date":"@date",//隨機日期
"float":"@float",//隨機浮點數
"name":"xxxx",//固定值
"quoteStrin1": "@name",//引用其他屬性
"user": {
"name": "demo"
},//固定值
"quoteString": "@user/name",//引用其他屬性
})
{
"date":"2020-06-29",
"float":2202285915843574.5,
"name":"xxxx",
"quoteStrin1":"xxxx",
"user ":{
"name":"demo"
},
"quoteString":"demo"
}
需要注意,如果引用的屬性名和 Mock 佔位符名稱一樣(上面例子中的 quoteStrin1),引用值優先級比佔位符高,所以最後 quoteStrin1 屬性值與屬性 name 的屬性值一致,而不是佔位符生成的值(Paul Miller)。
Mock 函數
1.Mock.mock
攔截請求,生成模擬數據
var data = Mock.mock("https://www.baidu.com", {
"string|1-10": "★", //隨機生成 1-10 個字符串"★"
})
var request = new XMLHttpRequest();
request.open("GET", "https://www.baidu.com", true);
request.send();
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
console.log(request.responseText)
}
}
直接生成模擬數據
var data = Mock.mock("https://www.baidu.com", {
"string|1-10": "★", //隨機生成 1-10 個字符串"★"
})
//{"string":"★★"}
2.Mock.Random
Mock.Random 是一個工具類,用於生成各種隨機數據。
Mock.Random 提供的完整方法如下:
| 類型 | 方法 | 備註 |
|---|---|---|
| Basic | boolean, natural, integer, float, character, string, range | |
| Date | date,time, datetime, now | |
| Image | image, dataImage | 生成圖片地址 |
| Color | color,hex,rgb,rgba,hsl | |
| Text | paragraph, sentence, word, title, cparagraph, csentence, cword, ctitle | |
| Name | first, last, name, cfirst, clast, cname | |
| Web | url, domain,protocol, email, ip, tld | |
| Address | region,province,city,county,zip | |
| Helper | capitalize, upper, lower, pick, shuffle | 方法,Mock.mock('@lower("HELLO")')->hello |
| Miscellaneous | uuid,guid, id,increment |
還可以使用 Random.extend 拓展佔位符,官網示例:
Random.extend({
constellation: function(date) {
var constellations = ['白羊座', '金牛座', '雙子座', '巨蟹座', '獅子座', '處女座', '天秤座', '天蠍座', '射手座', '摩羯座', '水瓶座', '雙魚座']
return this.pick(constellations)
}
})
Random.constellation()
// => "水瓶座"
Mock.mock('@CONSTELLATION')
// => "天蠍座"
Mock.mock({
constellation: '@CONSTELLATION'
})
// => { constellation: "射手座" }
參考資料
- Mock.js 文檔
- No API? No Problem! Rapid Development via Mock APIs-Cory House
- 莫池宇-你是如何構建 Web 前端 Mock Server 的?