继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