Testing Rake tasks with RSpec... and Rake

I’m of the (perhaps misguided) opinion that since Rake tasks are Ruby
code, they need to be tested. However, I’ve never done this before,
but thought it was worth looking into. So I wrote a simple RSpec test:

[[[[ ./test/spec.rb
describe “Rake tasks” do
require ‘rake’

before(:each) do
  @rake = Rake::Application.new
  # @rake.init                         # Uncomment and this test

will blow up.
# @rake.load_rakefile() # Uncomment and this test will blowup.
Rake.application = @rake
end

after(:each) do
  Rake.application = nil
end

it "should have at least one RSpec test to execute" do
  Rake.application["specs"].spec_files.size.should > 0
end

end
]]]]

There is a task called “specs” in my ./Rakefile.rb, which is a
Spec::Rake::SpecTask that just runs any file matching spec/**/*.rb. If
I inspect the Rake::Application instance I get when normally running
(with --trace), I get this:

#<Rake::Application:0x9c33154 @tasks={“specs”=><Rake::Task specs =>
[]>}, @rules=[], @scope=[], @last_description=nil, @name=“rake”,
@rakefiles=[“rakefile”, “Rakefile”, “rakefile.rb”, “Rakefile.rb”],
@rakefile=“Rakefile.rb”, @pending_imports=[], @imported=[],
@loaders={".rb"=>#Rake::DefaultLoader:0x9c32e28,
“.rf”=>#Rake::DefaultLoader:0x9c32d9c,
“.rake”=>#Rake::DefaultLoader:0x9c32d10},
@default_loader=#Rake::DefaultLoader:0x9c32ed0,
@original_dir="/home/johnf/dev/playground",
@top_level_tasks=[“tests:specs”], @tty_output=true,
@options=#<OpenStruct rakelib=[“rakelib”], trace=true>>

Notice the presence of @rakefile=“Rakefile.rb” and that the @tasks
hash is populated. (You can also see trace=true in the @options
OpenStruct.) However, if I inspect the Rake::Application instance that
I create inside test/spec.rb, it’s a lot sparser; in particular,
there’s no Rakefile loaded. Understandably, the spec test then fails,
saying that the Rake::Application instance doesn’t know how to run a
task called “specs”.

No problem; the documentation says you need to call #init on new
Application instances to get them primed. When I do that, however, the
Rake::Application instance inside the spec test exits abruptly, the
spec task fails, and the outer Rake instance complains “rake
aborted!”. The stacktrace ends at the spec-test level, presumably
because --trace isn’t turned on for the inner Rake::Application
instance. I also tried calling #load_rakefile() instead, but with
similarly unpromising results.

I’m a little stumped at this point, and am unable to divine anything
further from the documentation. What’s the right way to write this
spec?

~ jf