背景
ほとんどのアプリはサーバーAPIを連携して動くのが一般的ですね。
もし、サーバー側の開発が終わってない時はWebAPIがないまま開発することになる。これはよくあるパターンですが、APIがないまま開発するのは限界があるのでこんな時にスタブ環境構築しておけばとりあえずAPI連動開発もしやすくなります。
サーバー側からAPIが準備できなくても大体はインターペース定義書ぐらいはあるはずなのでそれを元にスタブを作り、ローカルでもテストができます。
今回、やりたいのは、
- Requestがあった場合、事前に定義したjsonファイルを読み込み、そのデータをResponseにしたい。
- 特定な
Host
やPath
で判定し、スタブで実行するかどうかを設定できるようにしたい。
ライブラリー導入
ネットで調べるとOHHTTPStubsがよく使われているらしいです。
Swiftでも使えるので問題なし。
使い方は上記のリンクで細かく説明がありますのでご参考を。
ます、入れましょう。
podfile
へpod追加します。
pod 'OHHTTPStubs/Swift'
そして、pod install
Response用Jsonファイル追加
Responseに連携したいプロジェクトにリソースとして追加します。
例) hoge.json
{
"args": {
"foo1": "bar1",
"foo2": "bar2"
}
}
コードを書く
ライブラリーインポート
import OHHTTPStubs
初期化処理のメソッド
private let stubHost = "test.hoge.com"
private let stubReponseDelay = 0.5 // Response遅延時間設定
private func initializeStubConfiguration() {
HTTPStubs.setEnabled(true) // StubをOnにする
// MARK: Add stub endpoint.
stubEndpoint(path: "/test/hoge", file: "hoge.json")
}
登録用メソッド
エンドポイントをjsonファイルとマッピングするメソッド。特定のHost
, Path
によりJSONファイルを制御するようにします。
private func stubEndpoint(path: String,
file: String,
status: Int32 = 200,
headers: [String: String]? = ["Content-Type": "application/json"]) {
/*
// Pathだけで判定してstub環境に切り替えならこれでいい。
stub(condition: isPath(path)) { _ in
let stubPath = OHPathForFile(file, type(of: self))
return fixture(filePath: stubPath!, status: status, headers: headers)
.requestTime(self.stubReponseDelay, responseTime:OHHTTPStubsDownloadSpeedWifi)
}
*/
stub { [weak self] (request) -> Bool in
guard let `self` = self else { return false }
return request.url?.path == path && request.url?.host == self.stubHost
} response: { _ -> HTTPStubsResponse in
let stubPath = OHPathForFile(file, type(of: self))
let response = HTTPStubsResponse(fileAtPath: stubPath!, statusCode: status, headers: headers)
response.requestTime = self.stubReponseDelay
response.responseTime = OHHTTPStubsDownloadSpeedWifi
return response
}
}
切り替え設定(おまけ)
Build Target
、Build Setting
値でスタブ環境の切り替えを行いたいので下記の様に設定しておく。
Build Setting->Add User-Defined Setting
を選択
STUB_ENABLED
を追加、値はYES
に入力
info.plist
にBuild Setting
に定義してある設定をしておく(Key追加)
StubEnabled -> ${STUB_ENABLED}
コードで読み込み
// NOTE: Stub設定がtrueの場合のみ実行
if let stubEnabled = Bundle.main.object(forInfoDictionaryKey: "StubEnabled") as? String, stubEnabled == "YES" {
initializeStubConfiguration()
}
以上