I've just decided to give a try to some mock framework for Ruby. Actually a mock framework, since I never used one seriously before. Among other options (FlexMock, RSpec and ruby-mock) I came across Mocha, which looked like a rather good framework. It's not trivial to decide on the best one because, aside from ruby-mock, which is pretty old, all of them perform equally well (or bad) in the opinions I found on the Web.
My immediate need was for a quick way to define stubs. The class I wanted to test would call some methods in another object which needed a specific behaviour. One method of that other object needed to provide the class under test with results which depended upon the parameters passed in. A pretty common scenario, I believe. However, the documentation does not state how to stub a method like that, when no particular order of calls is required. (It says you can set an expectation on the order parameters will be passed in and results returned, but that's beyond my needs.)
Mocha::Mock::stubs method may be invoked multiple times with the same method name, as I discovered trying it out. For each expectation returned you can set different parameters and return values, hence simulating an object that acts based on its parameters, without tying it to any particular order. Here's a test-case which creates a mock for a calculator object:
require 'mocha' class CalculatorTestCase < Test::Unit::TestCase def test_add calculator = mock calculator.stubs(:add).with(1, 2).returns(3) calculator.stubs(:add).with(3, 7).returns(10) assert_equal(3, calculator.add(1, 2)) assert_equal(10, calculator.add(3, 7)) end end
I still need to better explore the world of a mock framework, but am already feeling ashamed of not having tried it before. I'm sure from now on I'll write a lot less code inside test-case files.