模擬伺服器返回資料|掘金技術徵文

NEXT發表於2016-12-20

本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出
原文連結:模擬伺服器返回資料

背景

模擬伺服器返回的資料,在以下場景具有實際意義:

和伺服器開發協商好開發介面,但伺服器API尚未部署,想介面定義好就進行開發;
伺服器已部署,返回的資料不能測試到各種情況,希望返回期待資料測試邊界情況;

如果客戶端開發人員能不走伺服器,通過模擬資料返回,能提升開發效率和程式質量。

實現思路

本文主要講解兩種實現方式:

  1. 使用網路分析工具攔截客戶端請求,並返回偽造資料。
    優點:無需改變客戶端程式碼;不依賴客戶端平臺,android和ios都通用;
    缺點:依賴網路分析工具;除錯相對不靈活;

  2. 使用客戶端網路框架攔截請求並返回。
    優點:返回資料由客戶端程式碼決定,靈活易於除錯;
    缺點:需要改變客戶端程式碼;需要根據客戶端網路框架進行響應處理,不同的網路框架處理不一樣;

對於方案一,主要使用網路分析工具Charles進行攔截並返回,對於方案二,主要講解使用OkHttp作為網路框架,利用攔截器機制實現模擬返回。

使用Charles模擬資料

準備條件

  1. 客戶端需要連線到和電腦同一個網路(手機連線電腦發出的wifi)
  2. 官網下載安裝

配置

配置方法參考Charles:移動端裝置網路抓包
完成配置後,可以在Charles中檢測到手機的網路請求和響應。

轉接伺服器地址

模擬伺服器返回資料|掘金技術徵文
Charles 攔截原理

轉接伺服器地址是指,當客戶端請求地址B時,本應該向指定的伺服器請求資料,但Charles可攔截此ip地址,使不向伺服器地址請求,並且返回另外一臺伺服器模擬的資料。
首先,我們來生成模擬返回資料的api介面;
開啟mocky網址,輸入想偽造Body資料,點選Generate my HTTP Response按鈕生成http的url地址。
模擬伺服器返回資料|掘金技術徵文
mocky生成模擬地址

如圖,當點選www.mocky.io/v2/58592298… 時,返回json格式的資料。
有了模擬資料的api地址,接著設定需要模擬的api介面。經過配置後,Charles可檢測手機的網路請求,選擇需要模擬返回資料的網路請求介面,右鍵選擇Map Remote...
Map From為需要攔截的介面,Map To為模擬的api介面,此處我們填入www.mocky.io/v2/58592298…,如下圖:
模擬伺服器返回資料|掘金技術徵文
Charles 攔截ip地址

選擇標題欄Tool工具圖示,取消選擇Map Remote,再勾選Map Remote,讓設定的ip地址生效。此時,當客戶端請求原地址時,都會返回模擬ip地址的資料,效果圖如下:
模擬伺服器返回資料|掘金技術徵文
Charles 返回模擬資料

小結

以上,使用Mocky網路和Charles工具實現模擬資料返回,無需改變客戶端原有程式碼,但是,當需要改變客戶端返回的資料時,則需要重新生成http模擬地址,再次設定Charles Map to內容。

自定義OkHttp Interceptor模擬返回

以下內容假設使用者掌握OkHttp的簡單使用,重點講解自定義OkHttpInterceptor模擬返回資料。

OkHttp攔截器

模擬伺服器返回資料|掘金技術徵文
OkHttp 攔截器

如圖,OkHttp可在Request和Response中設定任意個數的Intercepor(圖中用圓圈標識),對請求體和響應體進行處理。藉助OkHttp Interceptor機制,建立一個MockIntercepor,模擬返回一個Response,虛線部分為模擬的Response。

程式碼實現

MockInterceptor程式碼如下:

public class MockInterceptor implements Interceptor{
    @Override
    public Response intercept(Chain chain) throws IOException {
        Gson gson = new Gson();
        Response response = null;
        Response.Builder responseBuilder = new Response.Builder()
                .code(200)
                .message("")
                .request(chain.request())
                .protocol(Protocol.HTTP_1_0)
                .addHeader("content-type", "application/json");
        Request request = chain.request();
        if(request.url().equals("http://url_whitch_need_to_mock")) { //攔截指定地址
            String responseString = "{\n" +    //模擬資料返回body
                    "\t\"code\": 200,\n" +
                    "\t\"message\": \"success\",\n" +
                    "\t\"data\": {}\n" +
                    "}";
            responseBuilder.body(ResponseBody.create(MediaType.parse("application/json"), responseString.getBytes()));//將資料設定到body中
            response = responseBuilder.build(); //builder模式構建response
        }else{
            response = chain.proceed(request);
        }
        return response;
    }
}複製程式碼

在debug模式下,將此Interceptor新增到網路請求的OkHttp中,即可對指定的api地址進行攔截,並且返回特定的資料。

小結

使用OkHttp的攔截機制,可實現改變部分程式碼則可模擬返回資料,返回的資料可在程式碼中設定,可使用工廠模式將模擬資料的生成變動程式碼放到Factory中。依賴網路請求框架,若原專案使用OkHttp或Retrofit作為網路框架,可輕易實現模擬介面。

引用

Charles:移動端裝置網路抓包
利用charles模擬Http請求和響應
Hack Retrofit (2) 之 Mock Server
OkHttp Interceptor

相關文章