Calling (invoking) rails rake tasks from within ruby, for testing, try 2 3

Posted by Tim Connor Thu, 21 Feb 2008 21:48:00 GMT

Yesterday I wrote a post on capturing the output of rake from a ruby call using backticks, because I wanted to do so in a test. Well, I had stubbed out, but got lazy and used yesterday’s date, so of course when I come in today the test fails. In the light of a new day my problem was obvious. If you call rake from a sub-shell, say via ``, of course your mocking will not exist in that process. So today, I had Another Wonderful Opportunity for Learning (there are acronyms for this that use a different word than wonderful): a chance to do it right.

It took a little digging to figure out how to get this to work right with the built-in rails tasks, so here you go:

require ‘rake’
require ‘rake/rdoctask’
require ‘rake/testtask’
require ‘tasks/rails’

def capture_stdout
s =
oldstdout = $stdout
$stdout = s
$stdout = oldstdout

Rake.application.rake_require ‘../../lib/tasks/metric_fetcher’
results = capture_stdout {Rake.application[‘metric_fetcher’].invoke}

I liberated capture_stdout from the rake tests themselves. In retrospect, I should have just looked there first. As TDD and especially BDD get even more widespread the tests are often the easiest place to look for good examples of usage.


Leave a comment

  1. Avatar
    Matt Scilipoti about 1 year later:

    Thanks for posting this.
    I’m always amazed when things appear on the web just a few days before I need them.

  2. Avatar
    Tim Connor about 1 year later:

    Matt, check the year on the date. ;)

  3. Avatar
    Dan about 1 year later:

    Tim, I simultaneously googled for “calling rake tasks from rails” and opened my IM client to send you a message asking how to do this. You’re not online at the moment, but your blog was like the second search result.

    It’s almost as good as the Real Thing.