Unit testing with Ruby (part 2)

In ruby, you can do this:

Class methods mocking

Class methods mocking

Hum. Static’s bad, don’t do static, mkay? Well, not necessarily. The fact that you can test class methods like this makes them much more usable than they are in C#, where using static all over the place brings your design to the dumpster pretty quickly. Still, the use of class methods usually covers for underlying design flaws, so it’s a technical debt and you should evaulate what is convenient to do case by case.

The above snippet is powered by mocha, a mocking framework for ruby. It has a JMock-like syntax and it provides you all the usual tools.

mock()

creates a mock object. You can set expectations on a mock object with

mock_object.expects(:method_name)

and stubs with

mock_object.stubs(:method_name)

Expectations are verified at the end of the test: if you’ve set an expectation for :method_name and that method isn’t called on the mock object before the end of the test, that test will fail (no need to VerifyAllExpectations or such). Instead, stubs do not fail the test if not called.
So, in the following example:
mock_example

if we remove the object.second call from the method run only the second test fill fail.

As seen before, you can set expectations and stubs not just on mocks but on any object, even class objects. Abusing of this feature, as to say in object = Object.new; object.expects(:method) ,  is probably not wise but as shown in the first snippet this allows testing of usually not testable situations.

You can force constraints on expectations using with(param_value) and you can return values with returns(value). For example, the following code:

mock_object = mock()
mock_object.expects(:get_capital).with('sweden').returns('stockholm')

Sets an expectation on mock_object for the method get_capital, the expectation is satisfied only if get_capital is called with the string 'sweden' and, if called that way, returns the string 'stockholm'. Of course you don’t need both clauses to be present togheter, mock_object.expects(:get_capital).with('sweden') and mock_object.expects(:get_capital).returns('stockholm') work just as expected. If you don’t set a return value for any given expectation/stub it will return nil.

stub_everything() returns a mock object that stubs every possible method call. The return value will always be nil.

More on mocha will be found on its documentation page.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s