yaakaito.org

iOS用テスティングサーバー NLTHTTPStubServer 0.4 を公開しました

NLTHTTPStubServer, Objective-C, Testing, iOS

こんにちは!うきょーです! NLTHTTPStubServer を0.4にアップデートしました。

最初にごめんなさいしておかなければいけないことがあります。

0.2.x 系との互換性がありません

ごめんなさい。0.1.x 0.2.x 系でのバグフィックスなどは、半年くらいは受け付けようと思っていますので、気軽にご連絡ください。

NLTHTTPStubServerって何

簡単に言えば、レスポンス登録を動的にできるHTTPサーバー for iOSです。 HTTP通信をするiOSアプリはたくさんあると思うのですが、これのテストを書く為に開発されました。

仕組みとしては結構単純で、ローカルにHTTPサーバーを立てて、そこにレスポンスを登録し、アプリ(HTTPClient)でそこへアクセスする、という感じです。 例えば /api/v1/fakefake.json を返してほしい、というケースであれば、

1
[[[server expect] forPath:@"/api/v1/fake"] andJSONResponseResource:@"fake" ofType:@"json"];

という風に記述すると、クライアントからここにアクセスしたときに、fake.jsonが返されます。 NSURLConnectionを使って書くと、

1
2
3
4
5
6
NSURL *api = [NSURL URLWithString:@"http://localhost:12345/api/v1/fake"];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:api]
                                   queue:[[NSOperationQueue alloc] init]
                       completionHandler:^(NSURLResponse *res, NSData *data, NSError *err) {
                         // dataに fake.json が返ってくる
                       }];

このようにhttp://localhost:12345/api/v1/fakeへアクセスすると、fake.jsonが返ってきます。

カテゴリを使ってレスポンスを入れ替えたりするライブラリなんかもありますが、それと比べて、副作用が起こりにくいのが特徴です。 またモックを差し込む、という行為を必要とせず、APIのエンドポイントを入れ替えるだけでよいので、実装自体に手をいれる必要もほとんどありません。

セットアップ

Cocoapodsでのセットアップが簡単です。

1
pod 'NLTHTTPStubServer'

NLTHTTPStubServer.hをインポートして使います。

1
#import "NLTHTTPStubServer"

機能

サーバーの取得

テスト用サーバーは sharedServer でインスタンスを取得することができます。

1
NLTHTTPStubServer *server = [NLTHTTPStubServer sharedServer];

clearで登録されているレスポンスをすべて削除し、綺麗な状態にすることができます。

1
[server clear];

tearDownなどでお使いください。

expect / stub /verify

0.2.x まででサポートされていたstubが廃止されました。stubというAPIは存在しますが、動作が異なっています。

expect

expectはレスポンスを登録する一般的な方法です。

1
[[server expect] forPath:@"/path"];

このように記述すると、/pathへレスポンスが登録されます。 これに対して、メソッドチェインの形式で、必要なものを付加していきます。

1
[[[server expect] forPath:@"/api/v1/fake"] andJSONResponseResource:@"fake" ofType:@"json"];

expectで登録されたレスポンスは、一度アクセスを受けてそれが返されると、自動的に消化さた状態になります。 /pathへ二度アクセスしても、レスポンスは返されません。(例外が投げられます。)

verify

expectされたものは、verifyによって、それが利用されたかを検証することができます。

1
2
3
4
5
[[server expect] forPath:@"/path"];

// http://localhost:12345/path へアクセスするコード

[server verify]; // /path へきちんとアクセスされているかを検証

stub

stubexpectと同じインターフェイスを持ちますが、永続的に登録されるレスポンスです。

1
[[server stub] forPath:@"/path"];

これは http://localhost:12345/path へアクセスを受けそれが返されても、消化された状態になりません。 また、verifyによる検証では、stubで登録されたものは無視されます

NLTPath

NLTPathは複雑なURLを表現するために使われる物で、現状では特にGETパラメーターに対応するための機能です。

1
2
3
4
[[server expect] forPath:[NLTPath pathWithPathString:@"/fake" andParameters:@{
        @"k1" : @"v1",
        @"k2" : @"v2",
}]];

このような記述をした場合、このレスポンスは /fake?k1=v1&k2=v2 または /fake?k2=v2&k1=v1 にマッチします。

anyValue

[NLTPath anyValue]を使う事で、値部分をワイルドカードにすることができます。

1
2
3
[[server expect] forPath:[NLTPath pathWithPathString:@"/fake" andParameters:@{
        @"k1" : [NLTPAth anyValue]
}]];

これは、/fake?k1=hogeeeeeeee/fake?k1=fugaaaaaaaaaa にマッチします。

付加可能な項目

メソッドチェインにより付加できる事ができる項目は以下です。

HTTP Method

1
[[server stub] forPath:@"/fake" HTTPMethod:@"Post"];

Status code

1
[[[server stub] forPath:@"/fake"] andStatusCode:200];

Simulate waiting

タイムアウトなどを再現することができます。

1
[[[server stub] forPath:@"/fake"] andProcessingTime:10.0f];

Checking POST body

POSTされた内容を調べる事が出来ます。

1
2
3
4
[[[server expect] forPath:@"/fake" HTTPMethod:@"POST"] andCheckPostBody:^(NSData *postBody) {
        NSString *postBodyString = [that toString:postBody];
        GHAssertEqualStrings(postBodyString, @"POST_BODY", nil);
    }];

Supporting Content-Types

自動的にContentTypeを付加してくれるものは以下です。

1
[[[server expect] forPath:@"/fake"] and{ContentType}Response...]
  • JSON
  • HTML
  • XML
  • Plain Text
  • Binary
    • application/octet-stream

カスタムのContent-Typeは、andContentTypeHeaderによって付加することができます。

バグなどの報告

Github Issueで受け付けています。(日本語可)