2012-11-09 75 views
2

我是Java開發人員,我用它來測試Java實體爲POJO。現在,使用Obj-C,我想爲從NSManagedObject繼承的實體(我使用CoreData進行持久化)執行相同的操作。NSManagedObject的單元測試[GHUnit]

比如我想測試我的客戶實體爲:

-(void)myTest { 
Customer *customer = [Customer alloc] init]; 
customer.name = @"toto"; 
GHAssertEqualStrings(customer.name, @"toto", @""); 
} 

但我遇到的錯誤是:

NSInvalidArgumentException 原因: - [客戶的setName:]:無法識別的選擇發送到實例...

所以我一直在與有關數據庫架構的URL的setUp加載所有的NSManagedObjectContext。現在,我實例化我的客戶作爲和它的作品:

Customers *customer = [NSEntityDescription 
insertNewObjectForEntityForName:kDataBaseCustomerKey inManagedObjectContext:ctx]; 

但它是測試一個「POJO」適當的方式?我想在沒有任何模型加載的情況下測試我的Customer類,因爲在這種情況下我不關心數據模型。

謝謝您的建議。

問候。

回答

5

這取決於您正在測試的內容。從概念上將核心數據模型從實際實現中分離出來有點困難;所以我通常在單元測試代碼中構建自己的堆棧。另一方面,如果你真的測試只依賴於實現NSManagedObject子類的代碼,那麼我認爲你已經概述的方法沒有任何問題。

僅供參考,如果你有興趣在如何重新創建堆棧單元測試,這裏就是我如何做到這一點。 (我只注意到你正在使用的不是GHUnitOCUnit - 它應該是相同的,但你可能會需要確保該模型中包含了GHUnit應用程序捆綁資源

創建一個類,從SenTestCase繼承,建立自己的核心數據與NSInMemoryStoreType堆有:

@implementation CCFCoreDataTestCase { 
    NSManagedObjectModel *_mom; 
    NSPersistentStoreCoordinator *_psc; 
    NSManagedObjectContext *_moc; 
    NSPersistentStore *_store; 
} 

@synthesize managedObjectContext = _moc; 

- (void)setUp { 
    [super setUp]; 

    NSArray *bundles = [NSArray arrayWithObject:[NSBundle bundleForClass:[self class]]]; 
    _mom = [NSManagedObjectModel mergedModelFromBundles:bundles]; 
    _psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_mom]; 

    _store = [_psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:NULL]; 
    STAssertNotNil(_store,@"Unable to create in-memory store"); 

    _moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
    [_moc setPersistentStoreCoordinator:_psc]; 
} 

- (void)tearDown { 
    [super tearDown]; 
    _mom = nil; _psc = nil; _moc = nil; _store = nil; 
} 

您所有的測試用例觸及核心數據應該從這個子類繼承假設你正在使用一個內存中存儲類型與您共建。並在每次測試中拆除模型,最大限度地減少任何依賴性並從一個未填充的模型開始爲每個測試。當然,沒有關於表演的承諾。

編輯:

我發現這個職位有幫助的核心數據的單元測試對象時 - Unit testing Core Data-driven apps

編輯2:

格雷厄姆·李(該文章的作者上方)有另一篇關於不依賴模擬的單元測試核心數據對象。請參閱this one上面描述的模式與他在第二個鏈接中所做的更一致。

+0

是的,我喜歡這個IN-MEMORY解決方案。謝謝它的工作(即使與GHUnit)。但這意味着我以前的解決方案使用了「生產」數據庫及其中的現有數據? – ragu89

+0

爲你的**編輯**:這篇文章很有趣,有了這個解決方案,我將能夠測試我的MockCustomer而不依賴於核心數據堆棧。但是..我不是每個實體創建一個Mock類的粉絲。這不是一個沉重的解決方案嗎?你對那個怎麼想的? – ragu89

+0

請參閱第二編輯。我依賴於我描述的模式 - 在測試中創建一個輕量級堆棧。在你之前的解決方案中,至少在GHUnit中,我不認爲你實際上在使用「生產」數據,這取決於你如何實例化NSManagedObjectContext,特別是因爲GHUnit不知道你的應用程序的持久存儲。 – FluffulousChimp