Test::Unit::MockObject not working

…so I downloaded the latest version of test-unit-mock from RAA:
[05-31 20:35 test-unit-mock Mock objects for Test::Uni…
Lib…/Devel… 0.02] and started playing with it.

I created a simple class named LightBulb which has instance methods
"on" and “off” which change its status. When an object of this class
comes into existance, the status is off. I want the methods “on” and
"off" to be in that order. Calling the method “on” on a lightbulb which
is already “on” does not bode well. Like wise for the method “off”.

Everything went fine until I tried using “strictCallOrder = true”.
I thought I would be able to use it for calls in a loop. But that is not
how it works.

Can anybody shed some light :wink: on how to acheive this elegantly?

···

class LightBulb

attr :status

def initialize
@status = :off
end

def on
if @status == :on
raise 'boom!'
else
@status = :on
puts 'ON’
end
1
end

def off
if @status == :off
raise 'baam!'
else
@status = :off
puts 'OFF’
end
0
end

end

tm = LightBulb.new

2.times {
p tm.on
p tm.off
}

puts ‘------ Mock Test Begins -------’

require 'test/unit’
require ‘test/unit/mock’

TmClass = Test::Unit::MockObject(LightBulb)

tmObj = TmClass.new
tmObj.setReturnValues(:on=>1,:off=>0,:status=>[true,false])
tmObj.setCallOrder(:on, :off)
tmObj.strictCallOrder = true
tmObj.activate

2.times {
p tmObj.on
p tmObj.off
}

tmObj.verify
#--------------------------------------------

Produces:

ON
1
OFF
0
ON
1
OFF
0
------ Mock Test Begins -------
1
0
1
0
Loaded suite C:/atest/tst_mock
Started

Finished in 0.0 seconds.

0 tests, 0 assertions, 0 failures, 0 errors
C:/ruby/lib/ruby/site_ruby/1.8/test/unit/assertions.rb:31:in assert_block': Call order assertion failed: Unexpected method :on called from C:/atest/tst_mock.rb:57 at 0.00000 (Test::Unit::AssertionFailedError) from C:/ruby/lib/ruby/site_ruby/1.8/test/unit/assertions.rb:29:in_wrap_assertion’
from C:/ruby/lib/ruby/site_ruby/1.8/test/unit/assertions.rb:33:in
assert_block' from C:/ruby/lib/ruby/site_ruby/1.8/test/unit/mock.rb:285:inverify’
from C:/atest/tst_mock.rb:60

tmObj.setCallOrder(:on, :off)

Here you said you expect two method calls…

tmObj.strictCallOrder = true
tmObj.activate

2.times {
p tmObj.on
p tmObj.off
}

… and here you actually call 4 methods, so …

C:/ruby/lib/ruby/site_ruby/1.8/test/unit/assertions.rb:31:in `assert_block’:
Call order assertion failed: Unexpected method :on called from

… the second call of :on is unexpected.

Regards,
Pit

···

On 4 Jun 2003 at 9:13, Shashank Date wrote:

Here you said you expect two method calls…

tmObj.strictCallOrder = true
tmObj.activate

2.times {
p tmObj.on
p tmObj.off
}

… and here you actually call 4 methods, so …

My bad !

I should have made it clear (especially in the subject line) that
I ** know ** why it is raising the error. That much I expected.

I just want to know, further, if there is any way to handle repetitions
like these. That is what I meant when I said earlier:

I thought I would be able to use it for calls in a loop. But that is not
how it works.

So it seems to me that CallOrder is limited to ** single ** execution of
the specified methods in that order.

Correct ?
– shanko

I should have made it clear (especially in the subject line) that
I ** know ** why it is raising the error. That much I expected.

Sorry for telling you the obvious.

I just want to know, further, if there is any way to handle repetitions
like these. That is what I meant when I said earlier:

I thought I would be able to use it for calls in a loop. But that is not
how it works.

So it seems to me that CallOrder is limited to ** single ** execution of
the specified methods in that order.

I’m still not sure what you want. Do you simply want to run the
specified methods in a loop like you showed in your example? Then you
could specify the call order like

tmObj.setCallOrder(*[:on, :off]*2)

but this again seems too obvious to me, so I’m sure I’m still missing
something.

Regards,
Pit

···

On 5 Jun 2003 at 9:02, Shashank Date wrote:

“Pit Capitain” pit@capitain.de wrote in message

Do you simply want to run the specified methods in a loop
like you showed in your example? Then you
could specify the call order like

tmObj.setCallOrder(*[:on, :off]*2)

Aha ! Perfect … exactly what I wanted.

but this again seems too obvious to me, so I’m sure I’m still missing
something.

You are missing the fact that I’m just dumb :wink:
Thank you very much …
– shanko