Hi Gareth,
Mocha hasn't been designed to be thread-safe, so I suspect the
concurrency in your tests is what's causing the problem. The fact that
your sleep statement had to be at the end of the test method probably
reflects the fact that the Mocha verification step happens at this
point and not in the teardown. The display of the "not all
expectations were satisfied" error message is not atomic with the
display of the list of "unsatisfied expectations", so I can only
assume that the former was happening before the last expectation was
satisfied and the latter was happening after the last expectation was
satisfied. The sleep will have delayed both these steps until after
the last expectation was satisfied.
I'm sure you're probably already aware of this, but the jMock guys
suggest [1] that it's better to ensure that tests using mock objects
are synchronous. They talk about separating the *logic* within a task
from the details of *how* tasks are run, using classes like
DeterministicExecutor and DeterministicScheduler [2]. Then it should
be possible to test the task logic in unit tests (single-threaded &
with mocking) and how the task is run in integration tests
(multi-threaded & without mocking). Nat Pryce has a nice presentation
about "Test-Driven Development of Asynchronous Systems" [3] which
might also be useful if you haven't seen it.
I'd be very open to suggestions for making Mocha easier to use in
JRuby and/or in multi-threaded scenarios. Perhaps it would help to
include Executor-type classes like the ones in jMock. Feel free to
fork the GitHub repository [4] ;-) and let us know if you need any
more help.
Cheers, James.
[1] http://www.jmock.org/threads.html
[2] http://www.jmock.org/javadoc/2.5.1/org/jmock/lib/concurrent/package-summary.html
[3] http://www.natpryce.com/presentations/software-craftsmanship-2009.pdf
[4] http://github.com/floehopper/mocha