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: https://gist.github.com/838520 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. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110222/3c62015c/attachment.html>
On Tue, Feb 22, 2011 at 6:13 AM, James Martin <jimmymartin at gmail.com> wrote:> 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: > https://gist.github.com/838520 > 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. >Eric Hodel recently blogged about this: http://blog.segment7.net/2011/01/06/how-to-sleep-in-tests Best, Michael Guterl
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. On Wed, Feb 23, 2011 at 6:37 AM, Michael Guterl <mguterl at gmail.com> wrote:> > > Eric Hodel recently blogged about this: > http://blog.segment7.net/2011/01/06/how-to-sleep-in-tests > > Best, > Michael Guterl >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110223/bf580a3b/attachment.html>