2010-06-24 15 views
13

Come posso aspettare che Scala Actor esca()? Ho impostato due attori in un test unitario e ho inviato alcuni messaggi per avviarli. Mandano alcuni messaggi avanti e indietro e alla fine entrambi chiamano exit(). Come faccio a fare in modo che il mio test unitario attenda che entrambi gli attori finiscano prima di passare?Attendi che un attore esca()

risposta

7

Se si conosce in anticipo il numero di messaggi scambiati tra gli attori, è possibile utilizzare uno java.util.concurrent.CountDownLatch per tenere traccia del conteggio dei messaggi. Negli attori, dopo ogni elaborazione del messaggio, fare

latch.countDown() 

e nel tuo thread principale fare

latch.await() 

questo renderà la vostra attesa principale filo fino al conteggio del latch è fino a zero.

Se non si conosce il conteggio dei messaggi in anticipo, ma è presente una condizione che indica la fine, è possibile utilizzare java.util.concurrent.locks.Condition. Nei attori, quando la sua condizione è soddisfatta, fare

if (conditionSatisfied) 
    condition.signal() 

e nel tuo thread principale fare

while (!conditionSatisfied) 
condition.await() 

per rendere più aspettare che la condizione è soddisfatta.

Vedere le javadoc di CountDownLatch e Condition per i dettagli.

Vedere this Gist per esempio di Condition.

+1

potevo conto alla rovescia() poco prima exit() e conta solo fino a 1. Ciò sembra ridondante, poiché i due metodi sarebbero sempre chiamati insieme. –

+0

Non capisco. Vuoi che il filo principale attenda fino a quando gli attori hanno finito, giusto? Questo è ciò che faranno le chiamate 'await()'. –

+0

Significa che devo aggiungere un latch o una condizione al codice di produzione (gli attori) esclusivamente per un test JUnit (in attesa degli attori). –

2

Nelle specifiche è possibile utilizzare Eventually Matchers. Se si conosce lo stato finale del vostro attore o qualsiasi entità (ad esempio, la persistenza negozio) esso modifica, potrebbe essere forza di prova di aspettare, fino a quando si verificherà il passaggio a questo stato:

<entity state> must eventually(10, 1.second)(be(<state>)) // there will be 10 retires every second, and if the state will be different, exception is thrown 
+1

Ciò farebbe sì che l'unità di prova impieghi circa un decimo di secondo per funzionare, il che è troppo lento. –

Problemi correlati