XCTestでAPIクライアントのテストを書くときに便利だったテストケースクラスの実装をシェアします。
その前に、そのテストケースクラスを使った時にどうなるかbefore/afterで比較しましょう。
beforeは元の自分のプロジェクトで使われた環境で書かれてたテスト風のサンプルコードで、afterが便利TestCaseクラスを利用したコードです。
before
基本的にはOHHTTPStubsを使ってHTTPのリクエストをstubして、TRVSMonitorを使って非同期処理の待ち状態を作ってました。
毎回stubの定義を書いたりmonitorオブジェクトなど作成したり、テスト書くのに全然集中できないし、読んでても余計なコード大石イライラしますね。
#import <XCTest/XCTest.h>
#import <OHHTTPStubs/OHHTTPStubs.h>
#import <TRVSMonitor/TRVSMonitor.h>
#import "AMEFooBarClient.h"
@interface AMEFooBarClientTests : XCTestCase
@end
@implementation AMEFooBarClientTests
- (void)setUp
{
[super setUp];
// Put setup code here; it will be run once, before the first test case.
}
- (void)tearDown
{
// Put teardown code here; it will be run once, after the last test case.
[OHHTTPStubs removeAllStubs];
[super tearDown];
}
- (void)testExample
{
__block NSURLRequest *lastRequest;
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { return YES; }
withStubResponse:^OHHTTPStubsResponse * (NSURLRequest *request) {
lastRequest = request;
return [OHHTTPStubsResponse responseWithFileAtPath:OHPathForFileInBundle(@"sampleResponse.json", nil)
statusCode:200
headers:@{@"Content-Type" : @"application/json"}];
}];
TRVSMonitor *monitor = [TRVSMonitor monitor];
__block NSArray *fooBars;
[[AMEFooBarClient new] fetchFooBarWithFooBarId:@1
completionHandler:^(NSArray *array, NSError *error) {
fooBars = array;
[monitor signal];
}];
[monitor wait];
XCTAssertTrue([[[lastRequest URL] path] isEqualToString:@"/api/v1/foo/bar/1"]);
XCTAssertTrue(fooBars[0][@"id"]);
}
after
stub定義するための簡単なhelperメソッドを定義しました。
TRVSMonitorは前準備がダルかったので、前準備の要らないTKRGuardに乗り換えました。
https://github.com/tokorom/TKRGuard
#import <XCTest/XCTest.h>
#import "AMEHTTPRequestTestCase.h"
#import "AMEFooBarClient.h"
@interface AMEFooBarClientTests : AMEHTTPRequestTestCase
@end
@implementation AMEFooBarClientTests
- (void)setUp
{
[super setUp];
}
- (void)tearDown
{
[super tearDown];
}
- (void)testExample
{
[self stubAllRequestWithResponseFileName:@"sampleResponse.json" statuCode:200];
__block NSArray *fooBars;
[[AMEFooBarClient new] fetchFooBarWithFooBarId:@1
completionHandler:^(NSArray *array, NSError *error) {
fooBars = array;
RESUME;
}];
WAIT;
XCTAssertTrue([[[self.lastRequest URL] path] isEqualToString:@"/api/v1/foo/bar/1"]);
XCTAssertTrue(fooBars[0][@"id"]);
}
スッキリしました。
↑のテストケースクラスの実装例はこちらです。
https://gist.github.com/ainame/3ca51dde36ea0e9e997e
以上、用途に応じてTestCase作るとすごい便利でテスト書くのに集中できていいですね〜っていうtipsでした。