37
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSAdvent Calendar 2012

Day 17

iOSでAPIのテストを気軽にかこう!

Last updated at Posted at 2012-08-17

こんばんは!8/17担当の dealforest こと森本です。
Qiita に投稿はありませんが決してスパムアカウントではありませんのであしからずw

さて、本題ですが iPhone アプリを作成していると API の連携が必要なケースが頻繁にあるかと思います。
テストを書くためにロジックに手を加えないといけないのは相当いけていないからなるべくやりたくありません。

自社サービスの API ならまだ融通がきくと思います。
しかしードパーティの API ともなると色々と制限があったりそうもいってられないケースもあるでしょう。
Twitter の場合だと API 通信の回数に制限もあったりし、テストのためとはいえ気軽に叩くのはいかんともしがたいものがあります。

という状況もあり自分に言い訳をしテストをかかなかった時も僕にはありました。

そんなときに Ruby の FakeWeb に出会いました。(深夜の通販風w)

FakeWeb はロードし対象の URL を登録するだけで、リクエストを偽装してくれる優れものです。
そのためロジックは何も修正する必要なく処理を実行することができます。
めっさいけてるやん!!と inspire し作りました。
本家の機能をほぼ実装しています。

dealforest/iOS-FakeWeb

使い方などはREADMEテストケースなどをみてもらえればと思います。
現状は ASIHTTPRequestNSURLConnection を利用した場合に対応しています。
Core でそれらを使っているのなら利用することができます。

以下、軽くさわりだけでもどうぞ。

Twitter の publick timeline にアクセスするだけの method をもったクラスがあったとします。

TwitterClient.h
@interface TwitterClient

-(NSString *) fetchPublicTimeline;

@end
TwitterClient.m
#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-FakeWeballending / Kiwi を用いて先にロジック部分をがっつり作るようになりましたとさ。

それでは良い週末を!

37
36
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
37
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?