LoginSignup
74
67

More than 5 years have passed since last update.

SwiftのQuickでAlamofireを使った非同期のテストを書く

Last updated at Posted at 2015-10-12

概要

HTTP通信を行うようなテストケースを書くには、通常、スタブを使います。
サーバが落ちていたりしてテストが失敗するケースがありますし、連続してリクエストするのはサーバのリソースを食いますし、遅いですし…。
SwiftのQuickでAlamofireを使ったテストを書くのに躓いたので、同じ人がいるかもと思い、筆(キーボード)を執りました。

環境

  • Xcode7(Swift2.0)
  • Quick
    • RSpec風にかけるテストライブラリです。
    • 非同期のテストも書け、今回はこの機能を使います。
    • XCTestなど他のテストフレームワークを使う場合は、TRVSMonitorとかで非同期のテストをするといいかもしれません(試してません)。TKRGuardはSwiftではマクロが使えないためか動きませんでした。
  • Nimble
    • Quickが依存するmatcher
  • Mockingjay
    • HTTPモックライブラリです。
    • 他にもOHHttpStubsが有名ですが、Quick + Alamofireとは相性が悪そうで断念。
  • Alamofire
    • 説明不要、事実上標準といっても過言ではないHTTPライブラリ
  • SwiftyJSON
    • こちらも有名なJSONパーサですね。

コード

http://api.pokosho.com/v1/hoge.json は以下のJSONを返す謎のAPIの予定です。

{ "name": "kaiba" }

が、まだ実装していないため、404が返ります。
正しい結果が得られた時のテストを書きます。

RequestHogeAPISpec.swift
import Quick
import Nimble
import Mockingjay
import Alamofire
import SwiftyJSON

class RequestHogeAPISpec: QuickSpec {
    var jsonData: JSON!
    var statusCode: Int = 0

    override func spec() {
        describe("hoge API") {
            context("when you request hoge API http://api.pokosho.com/v1/hoge.json") {
                beforeEach() {
                    // setup stub
                    let body = [ "name": "kaiba" ]
                    self.stub(http(.GET, uri: "http://api.pokosho.com/v1/hoge.json"), builder: json(body))
                }

                it("returns json") {
                    // request async
                    Alamofire.request(.GET, "http://api.pokosho.com/v1/hoge.json")
                        .responseJSON { request, response, result in
                            self.jsonData = JSON(result.value!)
                            self.statusCode = response!.statusCode
                        }
                    expect(self.statusCode).toEventually(equal(200))
                    expect(self.jsonData["name"]).toEventually(equal("kaiba"))
                }
            }
        }
    }
}

結果

Test Suite 'All tests' passed at 2015-10-12 23:42:19.177.
     Executed 1 test, with 0 failures (0 unexpected) in 0.041 (0.046) seconds

1つのテストが実行され、失敗はありませんでした!
(試しにわざと失敗になるように書き換えて見ると良いと思います)

解説

beforeEachでAPIのURLに対してスタブを登録しています。

RequestHogeAPISpec.swift
self.stub(http(.GET, uri: "http://api.pokosho.com/v1/hoge.json"), builder: json(body))

Alamofireの結果は非同期で帰ってくるため、QuickのtoEventuallyを使って、非同期に得られる値のチェックをしています。
今回はデフォルトのタイムアウトですが、引数でタイムアウトを指定することもできます。

RequestHogeAPISpec.swift
expect(self.statusCode).toEventually(equal(200))

追記 URLパラメータを付加するとき

以下のように正規表現を使って、stubを登録するとうまくいきます?

RequestHogeAPISpec.swift
self.stub(http(.GET, uri: "http://api.pokosho.com/v1/hoge.json?.*"), builder: json(body))

? ワイルドカードで hoge.json?* かも…? よくわからない。すみません。

追記

NSURLSessionConfiguration.mockingjaySwizzleDefaultSessionConfiguration()

終わりに

http://pokosho.com は僕の使ってるドメインです^^;
iOSやその他のプログラミング情報もありますので、良かったらどうぞ。

74
67
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
74
67