こんばんは!8/17担当の dealforest こと森本です。
Qiita に投稿はありませんが決してスパムアカウントではありませんのであしからずw
さて、本題ですが iPhone アプリを作成していると API の連携が必要なケースが頻繁にあるかと思います。
テストを書くためにロジックに手を加えないといけないのは相当いけていないからなるべくやりたくありません。
自社サービスの API ならまだ融通がきくと思います。
しかしードパーティの API ともなると色々と制限があったりそうもいってられないケースもあるでしょう。
Twitter の場合だと API 通信の回数に制限もあったりし、テストのためとはいえ気軽に叩くのはいかんともしがたいものがあります。
という状況もあり自分に言い訳をしテストをかかなかった時も僕にはありました。
そんなときに Ruby の FakeWeb に出会いました。(深夜の通販風w)
FakeWeb はロードし対象の URL を登録するだけで、リクエストを偽装してくれる優れものです。
そのためロジックは何も修正する必要なく処理を実行することができます。
めっさいけてるやん!!と inspire し作りました。
本家の機能をほぼ実装しています。
使い方などはREADMEやテストケースなどをみてもらえればと思います。
現状は ASIHTTPRequest と NSURLConnection を利用した場合に対応しています。
Core でそれらを使っているのなら利用することができます。
以下、軽くさわりだけでもどうぞ。
例
Twitter の publick timeline にアクセスするだけの method をもったクラスがあったとします。
@interface TwitterClient
-(NSString *) fetchPublicTimeline;
@end
#import "ASIHTTPRequest.h"
@implementation TwitterClient
-(NSString *) fetchPublicTimeline {
NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
return [request responseString];
}
@end
通常のリクエスト
TwitterClient *client = [[TwitterClinet alloc] init];
NSLog(@"%@", [client fetchPublicTimeline]);
このようなレスポンスが反ってくると思います。
リクエストを偽装した場合
#import "ASIHTTPRequest+FakeWeb.h"
[FakeWeb registerUri:@"http://api.twitter.com/1/statuses/public_timeline.json" method:@"GET" body:@"hoge" staus:200];
TwitterClient *client = [[TwitterClinet alloc] init];
NSLog(@"%@", [client fetchPublicTimeline]);
// hoge
まとめ
このように FakeWeb のカテゴリ(AHIHTTPRequest+FakeWeb.h or NSURLConnection+FakeWeb.h)を import し registerUri:method:body:status: で登録するだけでリクエストを偽装することができます。
テストなのでリクエストを送信しないように等、ロジックをいじる必要がまったくありません。
実装するに辺り Swizzle を利用し initialize 時に method を差し替えているのですが、その辺りは近々ブログにでも書きます。
API のレスポンスをファイルに直接書くのも微妙なので curl 等でリクエストした結果をファイルに保存しておき FakeWeb にはファイルから読み込み登録するようにすれば、ある程度きれいに書けるかと思います。
これで安心して気軽に何度もテストを回すことができますね!
CI との相性も良いかと思います。
TODO
- 現状だとARC必須になっているので非ARC環境でも動くようにする
- AFNetworking での動作検証(最近はやってますね)
- CocoaPods の対応
またバグ、改善等あれば気軽に pull req や連絡くださーい。
ということで最近は dealforest/iOS-FakeWeb と allending / Kiwi を用いて先にロジック部分をがっつり作るようになりましたとさ。
それでは良い週末を!