I’ve recently been playing around with some code that re-runs a block
until
either the block returns a non-false value, or a timeout expires:
At first, I thought this was working, as I was just checking the timing
of
the examples when returning a true value, however, now it looks like
sleep
isn’t being stubbed as I expect.
In the final example, the output from RSpec shows the time taken is 1
second, even though it’s sleeping for at least the full 10 seconds
specified
in the first argument to #do_this.
I can kind of imagine this not working at all, as the code relies on
calculations between two instances of Time.now.
Is there a better way to do this?
I’m really keen to get away from the whole Time.now/sleep combination in
my
tests if possible. I was thinking that perhaps a virtual clock would be
better, but then I’ve still got the sleep issue to deal with.
Thanks,
James.
On Tue, Feb 22, 2011 at 6:13 AM, James M. [email protected]
wrote:
calculations between two instances of Time.now.
Is there a better way to do this?
I’m really keen to get away from the whole Time.now/sleep combination in my
tests if possible. I was thinking that perhaps a virtual clock would be
better, but then I’ve still got the sleep issue to deal with.
Eric H. recently blogged about this:
http://blog.segment7.net/2011/01/06/how-to-sleep-in-tests
Best,
Michael G.
Thanks, Michael: That’s a useful article.
I attempted to emulate the example in RSpec but still found that
stubbing
sleep with any of the built in rspec-mocks wasn’t working the way I
hoped. I
was probably doing something wrong.
In the end I wrote a little module (Sleepy) that I can include in
RSpec.configure, which adds the #within method to the DSL. So now I can
say
something like this:
RSpec.configure do |c|
c.include(Sleepy)
end
describe “some long running method” do
it “takes no longer than thirty seconds to do its work” do
within 30.seconds do
some_long_running_method.should do_what_we_expect
end
end
end
And yes; I committed horrible atrocities duck punching Fixnum and Float
to
get the syntax reading nicely!
I suppose what I really wanted to be able to say was something like:
some_long_running_method.should_eventually do_what_we_expect
And be able to configure the maximum timeout of #should_eventually
Anyway, if this looks interesting or helpful for someone else I’ll throw
it
in a Gist.
Cheers,
James.