2013-10-30 31 views
1

我正在嘗試使用Restkit來執行與我們的應用程序需求相關的各種CoreData和JSON映射操作的服務類進行測試。該服務在通過iphone模擬器部署運行時工作正常,但在通過單元測試環境運行時掛起。RestKit CoreData在單元測試期間掛起

它似乎與Restkit中的線程使用有關,因爲我已經能夠將它縮小到以下類和方法調用。基本上,performBlockAndWait永遠不會返回。我對客觀世界非常陌生(不是一般的發展),所以任何幫助都將不勝感激。

Restkit類別:RKFetchRequestManagedObjectCache

方法:

- (NSSet *)managedObjectsWithEntity:(NSEntityDescription *)entity 
       attributeValues:(NSDictionary *)attributeValues 
     inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext 

... 

    // test hangs on this fetch call 
    [managedObjectContext performBlockAndWait:^{ 
     objects = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
    }]; 

我設立我CoreData測試堆具有以下:

NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(@"EventServiceTests")]; 
NSLog(@"Found bundle: %@", bundle); 

NSString *bundlePath = [bundle pathForResource:@"EventDataModel" ofType:@"momd"]; 
NSLog(@"Creating model from path: %@", bundlePath); 

NSURL *momURL = [NSURL URLWithString:bundlePath]; 
NSLog(@"URL for model: %@", momURL); 

NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 

RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]; 

    NSLog(@"Initializing the Core Data stack..."); 
    [managedObjectStore createPersistentStoreCoordinator]; 

    NSString* dataStorePath = [RKApplicationDataDirectory() stringByAppendingPathComponent: @"EventDataModel.dat"]; 
    NSLog(@"Persistent store file path: %@", dataStorePath); 

    NSURL *storeUrl = [NSURL fileURLWithPath: dataStorePath]; 

    if (![managedObjectStore.persistentStoreCoordinator addPersistentStoreWithType:NSBinaryStoreType configuration:nil URL:storeUrl options:nil error:&error]) { 
     NSLog(@"Issue creating persitent store: %[email protected]", error); 
    } 

    NSAssert(managedObjectStore.persistentStoreCoordinator.persistentStores, @"Failed to add persistent store: %@", error); 

    [managedObjectStore createManagedObjectContexts]; 

    NSLog(@"Setting the default store shared instance to: %@", managedObjectStore); 
    [RKManagedObjectStore setDefaultStore:managedObjectStore]; 

NSLog(@"Configuring the object manager..."); 
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://eventconsole.eng.techtarget.com/"]]; 
objectManager.managedObjectStore = managedObjectStore; 

NSLog(@"Setting shared manager instance to: %@", objectManager); 
[RKObjectManager setSharedManager:objectManager]; 

然後,使用執行請求操作:

NSString* url = UPCOMING_EVENTS_URL_PATH; 
NSLog(@"Attempting to get upcoming events from url: %@", url); 
[[RKObjectManager sharedManager] getObjectsAtPath:url parameters:nil 
     success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
      NSLog(@"Successfully loaded %@ upcoming events", 
      [NSString stringWithFormat:@"%ld", (unsigned long)[mappingResult count]]); 
      returnVal = TRUE; 
     } 
     failure:^(RKObjectRequestOperation *operation, NSError *error) { 
      NSLog(@"Error loading upcoming events: %@", error); 
      returnVal = FALSE; 
     } 
]; 

和實際測試代碼:

NSLog(@"Executing testLoadAttendees..."); 
[_eventService loadAttendees:@"2269"]; 
[NSThread sleepForTimeInterval:5.0f]; 
NSOperationQueue* queue = [RKObjectRequestOperation responseMappingQueue]; 
[queue waitUntilAllOperationsAreFinished]; 
+0

你如何設置您的測試環境(創建核心數據堆棧) ? – Wain

+0

更新後包括Restkit的樣本測試設置和服務方法的使用 – user2506488

+0

我應該真的問你試圖用你的測試證明什麼 - 它看起來像你的服務器工作,並且該RestKit工作。單元測試不應該用於這些事情。 – Wain

回答

2

我想出使用由RestKit提供的實用程序測試類的一種的溶液。

RKTestNotificationObserver *observer = 
    [RKTestNotificationObserver 
     notificationObserverForName:RKObjectRequestOperationDidFinishNotification 
           object:nil]; 
observer.timeout = 60; 
[observer addObserver]; 

NSLog(@"Executing testLoadAttendees..."); 
[_eventService loadAttendees:@"2269"]; 

[observer waitForNotification]; 

我包裹在一個實用方法:

- (void)executeAndTimeoutAfterSeconds:(int) timeoutSeconds usingBlock:(void(^)())block 
{ 
    RKTestNotificationObserver *observer = 
     [RKTestNotificationObserver notificationObserverForName:RKObjectRequestOperationDidFinishNotification object:nil]; 
    [observer addObserver]; 
    observer.timeout = timeoutSeconds; 
    block(); 
    [observer waitForNotification]; 
} 

所以測試使用的是現在執行:

[self executeAndTimeoutAfterSeconds:60 usingBlock:^ { 
    NSLog(@"Executing testLoadAttendees..."); 
    [_eventService loadAttendees:@"2269"]; 
}]; 
+0

我遇到了同樣的問題。感謝您的解決方案。 =) –