博客 / 詳情

返回

如何使用 Mock

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 的?
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.