LoginSignup
9
9

More than 5 years have passed since last update.

MagicalRecord+XCTestでテストを行う上での環境づくりの最適解は?【模索中】

Last updated at Posted at 2014-08-05

MagicalRecordいいですね。
Mogenerator + MagicalRecordでCoreData入門を参考に試している最中です。

ですがXCTestを使う上でハマったことがあり、最適な手段を模索中です。
もっといい方法があればご教示ください。

問題点

XCTestでModelのテストをする場合
以下のようにsetup,tearDownを記述しメモリ上でCoreDataを使うように設定すると思います。参考:unit-testing-with-core-data

SampleTests.m
@interface SampleTests : XCTestCase

@end

@implementation SampleTests

- (void)setUp
{
    [super setUp];
    [MagicalRecord setupCoreDataStackWithInMemoryStore];
}

- (void)tearDown
{
    [MagicalRecord cleanUp];
    [super tearDown];
}

//省略

問題はアプリ部分であるAppDelegateにもMagicalRecordの初期化が記述されるということ。

AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [MagicalRecord setupAutoMigratingCoreDataStack];
    return YES;
}


- (void)applicationWillTerminate:(UIApplication *)application
{
    [MagicalRecord cleanUp];
}

で、Testを実行するとAppDelegateの中も実行されるので、
[MagicalRecord setupAutoMigratingCoreDataStack];も実行されてしまい、CoreDataはファイルを使う設定にされてしまうようです。
で、テストが失敗するようになります。

対応策

テストを実行中はapplication:didFinishLaunchingWithOptions:等は何もしないようにしてしまいます。
更に、コード上でStoryBoardを読むようにして、テスト中はStoryBoardも見に行かないようにします(initialViewcontrollerがCoreDataにアクセスしている場合を考慮)

プロジェクト設定のGeneral->Deployment Info->Main Interfaceの中身を空欄にしておきます

AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    BOOL inTests = (NSClassFromString(@"XCTest") != nil);
    if (inTests) {
        return YES;
    }

    [MagicalRecord setupAutoMigratingCoreDataStack];

    //codeによるStoryBoard読み込みと表示
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    UIViewController *initialViewController = [storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initialViewController;
    [self.window makeKeyAndVisible];
    return YES;
}

//省略

- (void)applicationWillTerminate:(UIApplication *)application
{
    BOOL inTests = (NSClassFromString(@"XCTest") != nil);
    if (inTests) {
        return;
    }

    [MagicalRecord cleanUp];
}

Sampleをgithubにあげてみました。

9
9
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
9
9