Monday, November 27, 2006

Ruby mocking - Using flexstub

Ruby proves to be as sweet as most people have claimed it to be.

Pick testing and and you hit flexmock and flexstub.

So how do you use them? Here goes:

You have

class CA{
def method_1
do_some_processing
if condition method_2
else method_3
end

def method_2
do_some_slow_processing_worth_mocking_out
end

def method_3
do_some_more_slow_processing_worth_mocking_out
end

}

If you want to test method_1's conditonal logic, with method_2 and method_3 stubbed out, here is how you do it with flexstub:


require 'flexmock'

class MyTest< Test::Unit::TestCase
include FlexMock::TestCase
def test_method_1
ca = CA.new
# do something to make the condition be true
# stub some methods of the instance
stub = flexstub(ca)
stub.should_receive(:method_2).once
stub.should_receive(:method_3).never
ca.method_1
# Note: method_1 is invoked on ca.
# stub.method_1 will fail!
end
end


So when would you use flexmock?
If you wish to mock all the methods being called on an object, you may use a flexmock.
A flexmock is an object which will just receive the methods you set expectations for, using should_receive.
If you wish to mock only one of the methods of an object but the other methods need to be invoked with the real functionality,
use flexstub to mock only that particular method.

As you see, method_1 is invoked properly, but method_2 and method_3 are stubbed out.

One remarkable thing about this is mocking out an object's new method.

flexstub(Customer).should_receive(:new)
.and_return(mock_customer)

Anywhere Customer.new is called inside any class during your test, it will return a mock_customer.
This is quite powerful, because we no longer need to use dependancy injection for just test purposes.

So much for security!

If you are booking online on Spicejet, beware.
The lovely site which says verisign secured etc. actually sends all your credit card information as a query string!
So much for SSL!

I had written to them around 2 months back and it still remains the same!