Waiter
Class that facilitates performing assertions outside the main test thread, such as assertions in callback methods that are invoked asynchronously.
To use Waiter
, create an instance of it in the main test thread:
val w = new Waiter // Do this in the main test thread
At some point later, call await
on the waiter:
w.await() // Call await() from the main test thread
The await
call will block until it either receives a report of a failed assertion from a different thread, at which point it will complete abruptly with the same exception, or until it is dismissed by a different thread (or threads), at which point it will return normally. You can optionally specify a timeout and/or a number of dismissals to wait for. Here's an example:
import org.scalatest.time.SpanSugar._ w.await(timeout(300 millis), dismissals(2))
The default value for timeout
, provided via an implicit PatienceConfig
parameter, is 150 milliseconds. The default value for dismissals
is 1. The await
method will block until either it is dismissed a sufficient number of times by other threads or an assertion fails in another thread. Thus if you just want to perform assertions in just one other thread, only that thread will be performing a dismissal, so you can use the default value of 1 for dismissals
.
Waiter
contains four overloaded forms of await
, two of which take an implicit PatienceConfig
parameter. To change the default timeout configuration, override or hide (if you imported the members of Waiters
companion object instead of mixing in the trait) patienceConfig
with a new one that returns your desired configuration.
To dismiss a waiter, you just invoke dismiss
on it:
w.dismiss() // Call this from one or more other threads
You may want to put dismiss
invocations in a finally clause to ensure they happen even if an exception is thrown. Otherwise if a dismissal is missed because of a thrown exception, an await
call will wait until it times out.
Finally, to perform an assertion in a different thread, you just apply the Waiter
to the assertion code. Here are some examples:
w { assert(1 + 1 === 3) } // Can use assertions w { 1 + 1 should equal (3) } // Or matchers w { "hi".charAt(-1) } // Any exceptions will be forwarded to await
Here's a complete example:
import org.scalatest._ import concurrent.Waiters import scala.actors.Actor class ExampleSuite extends FunSuite with Matchers with Waiters { case class Message(text: String) class Publisher extends Actor { @volatile private var handle: Message => Unit = { (msg) => } def registerHandler(f: Message => Unit) { handle = f } def act() { var done = false while (!done) { react { case msg: Message => handle(msg) case "Exit" => done = true } } } } test("example one") { val publisher = new Publisher val message = new Message("hi") val w = new Waiter publisher.start() publisher.registerHandler { msg => w { msg should equal (message) } w.dismiss() } publisher ! message w.await() publisher ! "Exit" } }
Attributes
- Graph
-
- Supertypes
-
class Objecttrait Matchableclass Any