Hi!
What I''m trying at the moment is to build specifications for some
background thread code. What I want is a class Task and a class
TaskRunner. The TaskRunner should run a task in a background thread. It
should also indicate the status of the running task when calling the
running? method.
That''s basically, what I came up with so far:
class TaskRunner
def initialize
@is_running = false
end
def running?
return @is_running
end
def execute(task)
@is_running = true
Thread.new do
task.run
@is_running = false
end
end
end
class SampleTask
def run
end
end
context "The TaskRunner" do
setup do
Thread.stub!(:new).and_return do |block|
block.call
end
@runner = TaskRunner.new
end
specify "should be running when a task is executed" do
task = SampleTask.new
task.should_receive(:run) do
@runner.should_be_running
end
@runner.execute(task)
end
specify "should not be running after the task has been executed"
do
@runner.execute(SampleTask.new)
@runner.should_not_be_running
end
end
I don''t want to have real threads in the specs, so I mocked the Thread
class to just execute the passed block within the main thread. In the
first specification I also mock the run method of the task to check
within that method, if the TaskRunner correctly indicates it''s running
status. So far this works, but maybe there is a better solution. Any
suggestions?
Is there a way to use the above mocking of Thread.new and pass a
parameter to the block executed by the thread, like this?:
def execute(task)
@is_running = true
Thread.new(task) do |task_to_execute|
task_to_execute.run
@is_running = false
end
end
How can RSpec mock Thread.new in this case?
Maybe I should introduce some kind of ThreadFactory that creates
instances of TestableThread for the specifications.
bye,
Tobias
Hi!
Maybe my last (but real life) example was too boring - what about this one?
see end of mail or http://pastie.caboo.se/35443
So basically what I want to do, is mock a method that receives
parameters and a block, but I still need to execute the passed block in
order to test that it does what it is expected to do.
With a different design, I could avoid this problem. Instead of passing
blocks around I could e.g. use some kind of Strategy class.
I was just wondering if this can be done somehow with RSpec''s mocking
capabilities. If not, maybe RSpec can be extended to make it possible.
bye,
Tobias
Sorry, I hold no degree in Trek physics !!! :-)
class Antimatter
def stabilize
end
end
class TransWarpEngine
def TransWarpEngine.initiate(antimatter)
create_quantum_singularity
yield antimatter
end
end
class BorgCube
def travel_with_light_speed(antimatter)
TransWarpEngine.initiate(antimatter) do |antimatter|
antimatter.stabilize
end
end
end
context "The Borg Cube, when travelling with light speed" do
setup do
@borg_cube = BorgCube.new
end
specify "should initiate the TransWarpEngine with the given
antimatter" do
antimatter = mock(Antimatter)
TransWarpEngine.should_receive(:initiate).with(antimatter)
@borg_cube.travel_with_light_speed(antimatter)
end
specify "should tell the TransWarpEngine, that the antimatter should
be stabilized" do
antimatter = mock(Antimatter)
antimatter.should_receive(:stabilize)
#
# Put in here the part, that I don''t know how to do :-)
# I must mock or stub TransWarpEngine.initiate(), because I
can''t risk
# to create a quantum singularity when running RSpec.
# But i also must test, that my little BorgCube receives the correct
# instructions to stabilize the antimatter, otherwise my
customer won''t
# be very happy, when she tries out the BorgCube the first time
and it
# simply detonates because of unstabilized antimatter.
#
@borg_cube.travel_with_light_speed(antimatter)
end
end
Apparently Analagous Threads
- mocking methods that receive blocks - back to mocking Thread again
- Daily smb_trans2_request errors
- [PATCH v2 2/4] xen/arm: do not use is_running to decide whether we can write directly to the LR registers
- help to understand is_running _on_xen ?
- Running GUI applications in background