Mocha 0.5 released
sudo gem install mocha
or download one of the latest packages from rubyforge.
Parameter Matchers
I’ve added a few Hamcrest-style parameter matchers which are designed to be used inside Expectation#with
. The following matchers are currently available: anything()
, includes()
, has_key()
, has_value()
, has_entry()
, all_of()
& any_of()
. More to follow soon. The idea is eventually to get rid of the nasty parameter_block
option on Expectation#with
.
object = mock()
object.expects(:method).with(has_key('key_1'))
object.method('key_1' => 1, 'key_2' => 2)
# no verification error raised
object = mock()
object.expects(:method).with(has_key('key_1'))
object.method('key_2' => 2)
# verification error raised, because method was not called with Hash containing key: 'key_1'
Values Returned and Exceptions Raised on Consecutive Invocations
Allow multiple calls to Expectation#returns
and Expectation#raises
to build up a sequence of responses to invocations on the mock. Added syntactic sugar method Expectation#then
to allow more readable expectations.
object = mock()
object.stubs(:method).returns(1, 2).then.raises(Exception).then.returns(4)
object.method # => 1
object.method # => 2
object.method # => raises exception of class Exception
object.method # => 4
Yields on Consecutive Invocations
Allow multiple calls to yields on single expectation to allow yield parameters to be specified for consecutive invocations.
object = mock()
object.stubs(:method).yields(1, 2).then.yields(3)
object.method { |*values| p values } # => [1, 2]
object.method { |*values| p values } # => [3]
Multiple Yields on Single Invocation
Added Expectation#multiple_yields
to allow a mocked or stubbed method to yield multiple times for a single invocation.
object = mock()
object.stubs(:method).multiple_yields([1, 2], [3])
object.method { |*values| p values } # => [1, 2] # => [3]
Invocation Dispatch
Expectations were already being matched in reverse order i.e. the most recently defined one was being found first. This is still the case, but we now stop matching an expectation when its maximum number of expected invocations is reached. c.f. JMock v1. A stub will never stop matching by default. Hopefully this means we can soon get rid of the need to pass a Proc
to Expectation#returns
.
object = mock()
object.stubs(:method).returns(2)
object.expects(:method).once.returns(1)
object.method # => 1
object.method # => 2
object.method # => 2
# no verification error raised
This should still work…
Time.stubs(:now).returns(Time.parse('Mon Jan 01 00:00:00 UTC 2007'))
Time.now # => Mon Jan 01 00:00:00 UTC 2007
Time.stubs(:now).returns(Time.parse('Thu Feb 01 00:00:00 UTC 2007'))
Time.now # => Thu Feb 01 00:00:00 UTC 2007
Acknowledgements
Thanks to David Chelimsky, Dan North, Jay Fields, Kevin Clark, Frederick Cheung, James Moore, Brian Helmkamp, Ben Griffiths, Chris Roos & Paul Battley for their input. Apologies to anybody I forgot to mention.