繼TDD之後,我正在開發一款iPad應用程序,用於從互聯網下載一些信息並將其顯示在列表中,允許用戶使用搜索欄過濾該列表。帶有dispatch_async調用的測試代碼
我想測試一下,當用戶在搜索欄中輸入內容時,帶有過濾文本的內部變量被更新,項目的過濾列表被更新,最後表格視圖接收到一個「reloadData」消息。
這是我的測試:
- (void)testSutChangesFilterTextWhenSearchBarTextChanges
{
// given
sut.filterText = @"previous text";
// when
[sut searchBar:nil textDidChange:@"new text"];
// then
assertThat(sut.filterText, is(equalTo(@"new text")));
}
- (void)testSutReloadsTableViewDataAfterChangeFilterTextFromSearchBar
{
// given
sut.tableView = mock([UITableView class]);
// when
[sut searchBar:nil textDidChange:@"new text"];
// then
[verify(sut.tableView) reloadData];
}
注:更改「filterText」屬性觸發,現在實際的過濾過程,這在其他測試中進行了測試。
我的搜索欄委託寫的代碼爲這個工程確定如下:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
self.filterText = searchText;
[self.tableView reloadData];
}
的問題是,過濾該數據是成爲一個沉重的過程,現在的問題是在主線程期間所完成的,所以UI被阻止的時間。
因此,我覺得做這樣的:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray *filteredData = [self filteredDataWithText:searchText];
dispatch_async(dispatch_get_main_queue(), ^{
self.filteredData = filteredData;
[self.tableView reloadData];
});
});
}
,從而過濾過程在不同的線程中發生,當它已經完成,該表被要求重新加載其數據。
問題是......如何在dispatch_async調用中測試這些東西?
有沒有優雅除了基於時間的解決方案以外的方式嗎? (就像等待一段時間,並期望這些任務已經完成,不是非常確定的)
或者我應該把我的代碼放在不同的方式來使其更具可測性?
如果您需要知道,我使用OCMockito和OCHamcrest通過Jon Reid。
在此先感謝!
使用brakpoints和NSLogs可能對您有幫助嗎? – 2013-05-12 18:48:50
爲了什麼目的你有前兩種方法。 – 2013-05-12 18:49:26
Hi @ArpitParekh!這個想法是使用[單元測試](https://en.wikipedia.org/wiki/Unit_testing)自動測試我的代碼。這不是關於找到一個錯誤,而是爲了確保此代碼從現在開始正確運行。前兩種方法是來自我的測試套件的測試。檢查鏈接關於單元測試的更多信息:) – sergiou87 2013-05-12 20:46:44