Mocha is very nice expectation library for Ruby and it allows us to do some amazing things with our tests. Proper unit testing strategy is mostly outside the scope of this article, but basically unit tests should be stubbed in every way possible so that you make sure you’re only testing one thing or unit. Mocha allows a programmer to stub methods, expect certain methods to be called in order, create state machines in your tests, etc.
The only problem with Mocha and the community around it is that advanced topics are not well-documented, with the aforementioned state machines being the one exception.
The Basic Mocha Latte
Don’t care if a method gets called or what it returns and you don’t want it to break your test? Stub it!
Latte.any_instance.stubs(:stir)
Expect a method to be called once? Expect it (duh):
Latte.any_instance.expects(:stir)
Expect a method to be called on a specific object?
@my_latte = Latte.new @my_latte.expects(:stir)
Double Mocha Latte
Specifying expected parameters is simple, too:
Latte.any_instance.expects(:stir).with("spoon")
What about explicitly excluding a function. Never!
Latte.any_instance.expects(:stir).with("knife").never
Care about the return value?
Latte.any_instance.expects(:stir).with("spoon").returns(true)
Need a mock object? Easy…
@my_latte = mock('Latte') @my_latte.expects(:stir) Latte.expects(:new).returns(@my_latte)
Double Nonfat Mocha Latte No Whip, 155 Degrees
What about when you need a method to be called once with some parameters and again with different parameters?
Latte.any_instance.expects(:stir).with("spoon").once Latte.any_instance.expects(:stir).with("knife").never Latte.any_instance.stubs(:stir) # let any other calls to this method be caught and ignored
The same goes for return values:
Latte.any_instance.expects(:stir).with("spoon").returns(true).once Latte.any_instance.expects(:stir).with("knife").never Latte.any_instance.stubs(:stir).returns(true)
Sequencing calls is trickier if you’re expecting different return values or to raise exceptions. This is buried in the documentation of mocha. If you know what you’re looking for, you can find it, but if you don’t… well, aren’t you glad you’re here? This expectation sets up stir to return true, then false, then raise an exception.
Latte.any_instance.expects(:stir).with("spoon").returns(true). then.returns(false).then.raises(BentSpoonException)
Mocha Shared and Enjoyed
Looking for more? Comment below on what you’re trying to expect with Mocha and we’ll be glad to help out.