Dopo aver letto la domanda e alcuni commenti, sembra che quello che ti serve è una tecnica per unità di test operazioni asincrone. doSomething() restituisce immediatamente, ma si desidera che il codice di test attenda il suo completamento, quindi esegue alcune convalide.
Il problema è che il test non è a conoscenza dei thread generati dalla chiamata, quindi apparentemente non ha modo di aspettarli. Si può pensare a molti modi sofisticati (e probabilmente imperfetti) per risolvere questo problema, ma secondo me c'è un problema di progettazione qui. Un test unitario dovrebbe simulare un client di alcune API e non dovrebbe assumere nulla sull'implementazione; Dovrebbe solo testare la funzionalità, come riflesso dall'API e dalla sua documentazione. Pertanto, eviterei di provare a rilevare e tenere traccia dei thread creati dalla chiamata asynch. Invece, migliorerei l'API della classe testata, se necessario. La classe a cui appartiene la chiamata asynch dovrebbe fornire un meccanismo per rilevare la terminazione. Mi viene in mente 3 modi, ma ci sono probabilmente più:
1) Consentire la registrazione di un ascoltatore che viene comunicata una volta che l'operazione è completata
2) Fornire una versione sincrona dell'operazione. L'implementazione può chiamare la versione asynch e quindi bloccare fino al completamento. Se la classe non deve esporre un tale metodo, la sua visibilità può essere ridotta a pacchetto protetto, in modo che il test possa accedervi.
3) Utilizzando lo schema di attesa-notifica, su qualche oggetto visibile.
Se la classe non fornisce tale meccanismo, non è realmente verificabile e, peggio, probabilmente non è molto riutilizzabile.
fonte
2010-05-14 22:53:21
In realtà vorrei evitare questa soluzione, invece cercavo un modo migliore per eseguire questo tipo di test e forzare il thread principale ad attendere la fine dei suoi figli. – Mark
@Marco: puoi per favore elaborare? cosa c'è di sbagliato nella soluzione di Chris? –
Sto testando un metodo doSomething() che avvia internamente alcuni thread che aggiornano alcune tabelle db. Quello che mi piacerebbe fare è eseguire questo metodo all'interno del mio test JUnit e quindi verificare se tutte le modifiche sul database sono state salvate correttamente. È importante che il metodo doSomething() non unisca i thread quando vengono creati e quindi non posso adottare la soluzione join(). – Mark