iOSのユニットテスト
目的
- CoreDataを使うアプリのユニットテストをやりたい
ゴール
- 各モデルのユニットテストが出来れば。
- 画面のテストは別にする
手順
- 参考資料に従ってしようとしたら、Lion+Xcode 4.1では、CoreData Stack関連のソースをAppDelegateではなく、専用のDataStoreのようなクラスに抽出すれば、テストは普通に通れるようになってる。素晴らしい!
- 手順はDataStoreの抽出以外は特にないですが。
DataStoreクラスを追加
- ターゲットを選択する時、テストもチェックを入れる必要
- CoreDataTestAppDelegateにあるCore Data StackのメソッドをDataStoreに移す
- シングルトンにしたいので、クラスメソッドに変更する
- managedObjectContextをsharedContextに変更する
- sharedContext以外のメソッドは全部privateにする
CoreDataTestAppDelegateを整理
- .hファイルにある下記のプロパティとメソッドを削除
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory;
- .mファイルにある上記プロパティとメソッドの実装を削除
deallocメソッドにある下記内容も忘れずに削除
[__managedObjectContext release]; [__managedObjectModel release]; [__persistentStoreCoordinator release];
- DataStoreをインポート
#import "DataStore.h"
- self.managedObjectContextを[DataStore sharedContext]に変更する
- 二箇所がある
一旦ビルドして、エラーがないのを確認できるはず
テストクラスを修正
- DataStoreをインポート
#import "DataStore.h"
- 下記の内容をテストメソッドに書く
NSManagedObjectContext *context = [DataStore sharedContext]; NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context]; [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"]; // Save the context. NSError *error = nil; if (![context save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } STAssertNil(error, @"正常保存");