2015-02-07 31 views
0
測試塊

我與Objective-C的單元測試開始,我需要知道如何與OCMockito和Xcode的6和Xcode 6和OCMockito

我測試的交互器試塊,這個交互器應該返回一個數組作爲塊參數,我必須要求提供者文件中的元素。

這是我要測試的方法:

- (void)userPoiListsWithSuccessBlock:(MNBSavePoisInteractorSuccess)success { 
     self.poiListEntityArray = [self.poiListProvider poiListsForUser:self.loggedUser]; 
     self.poiListViewObjectArray = [self viewPoiListObjectListWithPoiLists:self.poiListEntityArray]; 
     success(self.poiListViewObjectArray); 
    } 

首先,我安裝,我要的元素使用

self.mockPoiListProvider = mock([PoiListProvider class]); 
    self.sut = [[MNBSavePoisInteractor alloc] initWithManagedObjectContext:self.coreDataStack.managedObjectContext andPoiListProvider:self.mockPoiListProvider]; 

- (UserEntity *)loggedUserMock { 
    UserEntity *mockLoggedUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([UserEntity class]) inManagedObjectContext:self.coreDataStack.managedObjectContext]; 
    [email protected]"1"; 
    [email protected]"user"; 
    [email protected]; 
    return mockLoggedUser; 
} 

- (InMemoryCoreDataStack *)coreDataStack{ 
    if (!_coreDataStack) { 
     _coreDataStack = [[InMemoryCoreDataStack alloc] init]; 
    } 
    return _coreDataStack; 
} 

- (PoiListEntity *)poiListFake { 
    PoiListEntity *fake = [NSEntityDescription insertNewObjectForEntityForName:@"PoiListEntity" inManagedObjectContext:self.coreDataStack.managedObjectContext]; 
    fake.name = @"Test"; 
    fake.poisCount = @2; 
    [fake addContributorsObject:[self loggedUserMock]]; 

    return fake; 
} 

於是,我做了測試。我使用Xcode 6 waitForExpectation來管理異步方法。我認爲我做錯了什麼。

- (void)waitForExpectation { 
    [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) { 
     if (error) { 
      NSLog(@"Timeout Error: %@", error); 
     } 
    }]; 
} 
- (void)testShouldReturnPoiLists { 
    XCTestExpectation *expectation = [self expectationWithDescription:@"Waiting method ends"]; 

    [given([self.mockPoiListProvider poiListsForUser:[self loggedUserMock]]) willReturn:@[[self poiListFake]]]; 

    [self.sut userPoiListsWithSuccessBlock:^(NSArray *results) { 
     [expectation fulfill]; 
      XCTAssert(resutls.count == 1, @"Results %zd", resutls.count); 
    }]; 
    [self waitForExpectation]; 
} 

我明白,如果我給在willReturn對象在給定的方法,當我打電話,我想測試它應該返回我以前給SUT方法。真的嗎? 謝謝

+0

我不明白你的測試方的意圖,因爲我不明白被測方法的意圖。你能解釋一下'-userPoiListsWithSuccessBlock:'是什麼,你想測試什麼? – 2015-02-07 20:54:22

+0

對不起@JonReid,實際上這不是真正的方法。我已經更新了它。這個方法返回一個''的數組。該陣列有兩種符合協議的對象。 PoiListProvider方法返回實體項目。第二種方法返回'',它們是我從實體和三個自定義對象轉換而來的'Ponsos'。我想測試結果數組是否具有我需要的相同數量的對象。我想如果我用這個實體設置'willReturn',我會在該塊中捕獲它。我很抱歉,我不明白我應該怎麼做這個測試 – croigsalvador 2015-02-09 19:48:48

回答

1

我看不到異步代碼。您只需要一個可捕獲結果的塊,因此請使用__block變量使結果在塊外部可用。那麼你可以斷言任何你想要的:

- (void)testShouldReturnPoiLists { 
    [given([self.mockPoiListProvider poiListsForUser:[self loggedUserMock]]) willReturn:@[[self poiListFake]]]; 
    __block NSArray *capturedResults; 

    [self.sut userPoiListsWithSuccessBlock:^(NSArray *results) { 
     capturedResults = results; 
    }]; 

    assertThat(capturedResults, hasLengthOf(1)); 
} 

長度1和假的關係很難說。讓我們也參數化僞造代碼:

- (PoiListEntity *)poiListFakeWithName:(NSString *)name count:(NSNumber *)count { 
    PoiListEntity *fake = [NSEntityDescription insertNewObjectForEntityForName:@"PoiListEntity" inManagedObjectContext:self.coreDataStack.managedObjectContext]; 
    fake.name = name; 
    fake.poisCount = count; 
    [fake addContributorsObject:[self loggedUserMock]]; 
    return fake; 
} 

因此,我們可以編寫更有趣的測試。

我想補充一點,「聽聽測試」很重要。有很多令人費解的設置在Core Data上跳舞。這告訴我,如果你可以重寫獨立於核心數據的東西 - 完全不知道它 - 一切都會更簡單。

+0

對不起@JonReid,我很忙,我無法嘗試,但它的工作。我有一個新問題,我應該怎麼做如果'poiListProvider'調用帶有'block'的方法,該方法給了我一個'NSArray',那就是我在'successBlock'中作爲參數傳遞的'result NSArray'?我應該在交互器中測試什麼?當我調用'interactctor userPoiListWith ...'時,我應該驗證他是否調用poiList方法?我應該在塊中測試返回的參數嗎?我很抱歉,但我不太清楚。如果您願意,我可以發佈一個新問題。謝謝 – croigsalvador 2015-03-05 23:28:50

+0

是的,一個新問題可能會有幫助。 – 2015-03-06 03:33:19