not all expectations were satisfied, but no problems listed

859 views
Skip to first unread message

reevesy

unread,
Oct 26, 2009, 10:01:06 AM10/26/09
to mocha-developer
I am getting the following weird behaviour from Mocha. The test fails
saying that now all expectations for satisfied but then doesn't list
any unsatisfied expectations. I was able to make things work
consistently by adding a short sleep of 0.1. It had to be at the end
of the test method, and didn't work when I put it in teardown.

I am using jruby (real threads) and my tests involve quite a lot of
concurrency.

Gareth

1) Failure:
test_capture(TestRequestReply):1:
not all expectations were satisfied
satisfied expectations:
- expected exactly once, already invoked once:
#<Mock:store>.write_response('In Request', 'Out Message')
- expected exactly once, already invoked once:
#<Mock:store>.write_request('In Request')
- allowed any number of times, not yet invoked: #<Mock:store>.base_path
(any_parameters)
- allowed any number of times, not yet invoked:
#<Mock:actual_store>.base_path(any_parameters)
- allowed any number of times, not yet invoked:
Compass::RequestReplyMessageStore.new(nil, nil, 'name.actual',
Compass::Compare::Simple)
- allowed any number of times, not yet invoked:
Compass::RequestReplyMessageStore.new(nil, nil, 'name',
Compass::Compare::Simple)
- allowed any number of times, already invoked once:
Compass::RequestReplyMessageStore.new(nil, nil, 'name.actual', nil)
- allowed any number of times, already invoked once:
Compass::RequestReplyMessageStore.new(nil, nil, 'name', nil)

James Mead

unread,
Oct 26, 2009, 11:47:28 AM10/26/09
to mocha-d...@googlegroups.com
2009/10/26 reevesy <ree...@gmail.com>:

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

Reply all
Reply to author
Forward
0 new messages