In seguito a TDD Sto sviluppando un'app per iPad che scarica alcune informazioni da Internet e le visualizza in un elenco, consentendo all'utente di filtrare tale elenco utilizzando una barra di ricerca.Codice di prova con chiamate dispatch_async
Voglio testare che, quando l'utente digita nella barra di ricerca, la variabile interna con il testo del filtro viene aggiornata, l'elenco filtrato di elementi viene aggiornato e infine la vista tabella riceve un messaggio "reloadData".
Queste sono le mie prove:
- (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];
}
NOTA: La modifica della proprietà "filterText" si innesca in questo momento il processo di filtraggio vero e proprio, che è stato testato in altri test.
Questo funziona male come il mio codice Searchbar delegato è stato scritto come segue:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
self.filterText = searchText;
[self.tableView reloadData];
}
Il problema è che il filtraggio questi dati sta diventando un processo pesante che in questo momento si sta facendo sul thread principale, così in quel tempo in cui l'interfaccia utente è bloccata.
Pertanto, ho pensato di fare qualcosa di simile:
- (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];
});
});
}
In modo che il processo di filtraggio si verifica in un thread diverso e quando ha finito, la tabella viene chiesto di ricaricare i propri dati.
La domanda è ... come posso testare queste cose all'interno delle chiamate dispatch_async?
C'è qualche elegante modo di fare altro che soluzioni temporali? (come aspettare un po 'di tempo e aspettarsi che quei compiti siano finiti, non molto deterministici)
O forse dovrei mettere il mio codice in un modo diverso per renderlo più testabile?
Nel caso sia necessario sapere, sto usando OCMockito e OCHamcrest entro il Jon Reid.
Grazie in anticipo !!
L'utilizzo di brakpoint e NSlog può aiutarti? –
Per quale motivo si hanno i primi due metodi. –
Ciao @ArpitParekh! L'idea sta usando [unit test] (https://en.wikipedia.org/wiki/Unit_testing) per testare automaticamente il mio codice. Non si tratta di trovare un bug, ma di assicurare che questo codice si comporti correttamente da ora in poi. I primi due metodi sono i test della mia suite di test. Controlla il link sul test dell'unità per maggiori informazioni :) – sergiou87