T
Thiago Arrais
Rubysts,
I am looking for a library for mocking objects.
I am aware of FlexMock and Test::Unit::Mock (seems like RubyMock
turned into Test::Unit::Mock, am I right?), but what I am looking for
would be something more like a hybrid of the two. Maybe I am really
misguided here, but this are my (admitedly first) impressions about
both.
FlexMock works by creating a full-blown, ready-to-use, suited-to-your
needs mock object in one method call (namely FlexMock.use). Then you
can just inject it into your tested object and use it.
Test:Unit::Mock mocks, on the other side, are created with (almost) no
idea of what will they be used for. Instead, they are born in a state
in which they still need to be told what they should expect. After you
have told them everything you want to happen to them (and how they
should respond), you switch them to replay state by calling the
#activate method. With FlexMock, there is no need to switch states,
because all the setup is done before the object is created. It is like
the mock is already born in replay state.
My main complaint about Test::Unit::Mock is about the big verbose
setup phase. With it you need to call a number of 'set' methods before
doing your stuff. In my opinion, this setup code can get pretty big,
pretty fast. For instance, let's take the example from
http://www.deveiate.org/projects/Test-Unit-Mock/wiki/Examples
Here we want to write a mock for a TCP socket. We want its 'addr'
method to return one of three values on each consecutive call, so we
write
mockSocket.setReturnValues( :addr =3D> [
["AF_INET", 23, "localhost", "127.0.0.1"],
["AF_INET", 80, "slashdot.org", "66.35.250.150"],
["AF_INET", 2401, "helium.ruby-lang.org", "210.251.121.214"],
] )
After setting up the return values for the other methods, we specify
the call order with
'setCallOrder'
mockSocket.setCallOrder( :addr, :getsockopt, :write, :read,
:write, :read )
I like the idea of the setup phase. I just don't like the particular
way it is done in Test::Unit::Mock. I prefer the record/playback
metaphor, where you actually call the methods you want to be called on
the record phase and then the object under test is responsible for
making the expected calls on playback phase. For instance, I would
like to write something like this:
# mockSocket starts in record state
mockSocket.addr do
return "AF_INET", 23, "localhost", "127.0.0.1"
end
mockSocket.getsockopt do
# getsockopt return stuff here
end
# we switch it to playback state here
mockSocket.activate
Is there already anything along these lines? Am I totally lost because
the libs I just listed already do that? Any ideas?
Cheers,
Thiago Arrais
I am looking for a library for mocking objects.
I am aware of FlexMock and Test::Unit::Mock (seems like RubyMock
turned into Test::Unit::Mock, am I right?), but what I am looking for
would be something more like a hybrid of the two. Maybe I am really
misguided here, but this are my (admitedly first) impressions about
both.
FlexMock works by creating a full-blown, ready-to-use, suited-to-your
needs mock object in one method call (namely FlexMock.use). Then you
can just inject it into your tested object and use it.
Test:Unit::Mock mocks, on the other side, are created with (almost) no
idea of what will they be used for. Instead, they are born in a state
in which they still need to be told what they should expect. After you
have told them everything you want to happen to them (and how they
should respond), you switch them to replay state by calling the
#activate method. With FlexMock, there is no need to switch states,
because all the setup is done before the object is created. It is like
the mock is already born in replay state.
My main complaint about Test::Unit::Mock is about the big verbose
setup phase. With it you need to call a number of 'set' methods before
doing your stuff. In my opinion, this setup code can get pretty big,
pretty fast. For instance, let's take the example from
http://www.deveiate.org/projects/Test-Unit-Mock/wiki/Examples
Here we want to write a mock for a TCP socket. We want its 'addr'
method to return one of three values on each consecutive call, so we
write
mockSocket.setReturnValues( :addr =3D> [
["AF_INET", 23, "localhost", "127.0.0.1"],
["AF_INET", 80, "slashdot.org", "66.35.250.150"],
["AF_INET", 2401, "helium.ruby-lang.org", "210.251.121.214"],
] )
After setting up the return values for the other methods, we specify
the call order with
'setCallOrder'
mockSocket.setCallOrder( :addr, :getsockopt, :write, :read,
:write, :read )
I like the idea of the setup phase. I just don't like the particular
way it is done in Test::Unit::Mock. I prefer the record/playback
metaphor, where you actually call the methods you want to be called on
the record phase and then the object under test is responsible for
making the expected calls on playback phase. For instance, I would
like to write something like this:
# mockSocket starts in record state
mockSocket.addr do
return "AF_INET", 23, "localhost", "127.0.0.1"
end
mockSocket.getsockopt do
# getsockopt return stuff here
end
# we switch it to playback state here
mockSocket.activate
Is there already anything along these lines? Am I totally lost because
the libs I just listed already do that? Any ideas?
Cheers,
Thiago Arrais