開發小技巧-mock

王天池發表於2018-12-20

開發小技巧-mock

我們在開發過程中,很多時候可能都需要Mock一個後臺,原因可能是下面兩種:

  • 後臺沒開發完,只有文件,前端開發又需要資料來方便開發
  • 測試需要,我們單元測試需要各種情況,很多情況是我們正常情況後臺無法提供的,而且顯然我們也不應該向真實後臺提交各種測試資料。

那麼針對上面兩種不同的需求,我們提供不同的方案

為了方便開發

對於這種需求我個人覺得最好可以不要在專案中寫關於mock的程式碼,這裡推薦兩種方案,兩種方案都幾乎不需要在專案中寫關於mock的程式碼,只需要修改專案中伺服器地址就好了。

Postman

postman是一款非常常用的模擬請求的工具,相信大家對他都不陌生。postman方案的優勢就是有UI頁面,可操作起來更直觀一些

首先我們點選左上角的new按鈕

然後選擇Mock server

Screen Shot 2018-12-16 at 6.44.32 PM

然後按照提示一步一步,設定路徑,設定response內容等等一些內容

Screen Shot 2018-12-16 at 6.46.53 PM

Screen Shot 2018-12-16 at 6.46.53 PM

如果設定後還需要修改返回內容,參考下圖,點選右上角的按鈕就可以進行修改

Screen Shot 2018-12-16 at 6.51.31 PM

Screen Shot 2018-12-16 at 6.52.38 PM

moco

moco是一個java的後端,下載安裝之後,我們就可以直接編寫一個JSON格式的檔案,一行命令便可以完成這個使命

使用時就將你的app host地址改為localhost:設定的埠,然後就可以獲取之前你寫好的json資料

java -jar pathto/Moco-runner-<version>-standalone.jar http -p 12306 -c pathTo/foo.json

需要注意的是,如果開了全域性翻牆,需要改成auto proxy mode,否則請求就會失敗

為了測試

這種為了單元測試的情況,雖然上面提到的方案其實也是可以完成測試的,但是還需要依賴專案外的環境設定,不是那麼完美。那麼我們就有必要把程式碼寫在專案中,以實現不依賴專案外的環境完成測試

其實這裡準確的說法應該是Stub

假定我們是使用Apple自帶的XCTest

由於網路請求是非同步的,所以單元測試需要使用XCTestExpectation waitForExpectations fullfile配合完成測試,這部分就不再贅敘了,我們就直奔主題

我們需要一個第三方庫的幫助,OHHTTPStubs

這個庫主要是把你的請求攔截下來,然後返回你指定的內容,可以是你寫好的json檔案

我們先設定好stub,我們把URL最後一部分是“listItems”的請求攔截下來,返回httpStub.json檔案中的內容。這裡其實可以設定其他的內容,比如把某個Host的請求全部攔截了,這都是可以設定的,大家可以看下OHHTTPStubs倉庫中的demo

- (void)installStubs {
    [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
        return [request.URL.lastPathComponent isEqualToString:@"listItems"];
    } withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
        return [[OHHTTPStubsResponse responseWithFileAtPath:OHPathForFile(@"httpStub.json", self.class)
                                                 statusCode:200
                                                    headers:@{@"Content-Type":@"application/json; charset=utf-8"}]
                requestTime:0.5f
                responseTime:OHHTTPStubsDownloadSpeedWifi];
    }];
}
複製程式碼

這個方法需要在測試真正開始前配置好,所以我們在setUp方法中呼叫installStubs

- (void)setUp {
    // Put setup code here. This method is called before the invocation of each test method in the class.
    [self installStubs];
}
複製程式碼

我們command+U測試一下,返回了我們json檔案中的內容。到這裡我們就完成了測試中模擬資料的部分

總結

我們文章中介紹了三種方式,其實我個人是最喜歡最後一種,為什麼呢?

首先,他完全可以在取代前面兩種方式,而且不依賴網路不依賴第三方軟體,雖然侵入了專案,但是好在不是很多,可以通過IF DEBUG的方式確保就算我們忘記移除,也不會影響release的版本。

再其次,為了做了這個就基本完成了這個介面網路請求的單元測試用例,簡直一舉兩得,雖然iOS開發這個領域,測試並沒有那麼普及,大家也普遍沒有做這項工作,但是測試確實是保證專案質量的重要方式,養成寫測試用例的習慣可以幫我們提前發現很多的bug。

參考資料

moco

Postman Setting up a mock serve

Real-World Testing with XCTest

The complete guide to Network Unit Testing in Swift

Asynchronous Tests and Expectations

isKindOfClass doesn't work as expected

測試中 Fakes、Mocks 以及 Stubs 概念明晰

相關文章