More Fun with Times, Mocks, and Closures
May 24th, 2007
I solved a complex problem in cruise today with some non-trivial mocking. Check this one out :
I needed to test that every x amount of time, we do a clean checkout. It can be every 6 hours, 2 days, whatever. How do you test this?
Well, maybe you could mock the time.
Time.stubs(:now).returns(Time.now + 2.hours) |
That almost works, except that the code works by touching a file. And touch doesn’t use Time.now. Now at this point, we could go crazy, and mock FileUtils.touch, of course that means we’ll also have to mock File.exists? and then what are we really testing?
Instead, I used Mocha to temporarily replace FileUtils.touch with my own implementation that acts like the original but uses my own value of time. It looks like this so far.
1 2 3 4 5 6 7 8 |
marker = sandbox.root + '/last_clean_checkout_timestamp' now = Time.now FileUtils.stubs(:touch).with(marker).returns(proc do File.open(marker, 'w') {|f| f << ''} File.utime(now, now, marker) end) Time.stubs(:now).returns proc { now } |
you’ll notice that both of these stubs are returning procs that reference now a local variable….
That’s ruby magic.
It means that I can now forget about mocks and write the rest of my test like this :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@project.do_clean_checkout :every => 1.hour assert @project.do_clean_checkout? assert !@project.do_clean_checkout? now += 59.minutes assert !@project.do_clean_checkout? now += 2.minutes assert @project.do_clean_checkout? assert !@project.do_clean_checkout? @project.do_clean_checkout :every => 2.days now += 1.day + 23.hours assert !@project.do_clean_checkout? now += 2.hours assert @project.do_clean_checkout? |
Instead of changing the mocks several times in between each test, I can just change my local variable now. Because of closures, the mocked out methods return the new value.
Ruby is awesome (and Mocha is pretty sweet too)
1 Response to “More Fun with Times, Mocks, and Closures”
Sorry, comments are closed for this article.

May 24th, 2007 at 06:11 PM JSS this is good stuff!