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 Date.today 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 = StringIO.new
oldstdout = $stdout
$stdout = s
yield
s.string
ensure
$stdout = oldstdout
end

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.

Comments

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.

Comments