codahale.com٭blog

This is my old blog. My current writing is here: codahale.com

Rake vs. RSpec! Fight!

I love RSpec, and lately I’ve been making the transition from test-friendly development to full-on spec-driven development. I still toss around some code for proofs of concept or to prototype APIs, but when the time comes to write serious code, I always begin with a spec.

I was working on a project recently which boiled down to “run these tasks in this order,” which is a natural fit for Rake. I have lots of beef with Rake, but I was able to back away from the yak-shaving precipice with this:

def describe_rake_task(task_name, filename, &block)
  require "rake"

  describe "Rake task #{task_name}" do
    attr_reader :task

    before(:all) do
      @rake = Rake::Application.new
      Rake.application = @rake
      load filename
      @task = Rake::Task[task_name]
    end

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

    def invoke!
      for action in task.instance_eval { @actions }
        instance_eval(&action)
      end
    end

    instance_eval(&block)
  end
end

Drop that in your spec_helper.rb and you can do stuff like this:

describe_rake_task "build:my_thing", "lib/tasks/my_thing.rake" do

  it "should build my other thing first" do
    task.prerequisites.should include("build:my_other_thing")
  end

  it "should do something" do
    @built_my_thing = false
    Builder.should_receive(:build).with(:my_thing)
    invoke!
    @built_my_thing.should be(false)
  end

end

Which, when run, produces this:

Rake task build:my_thing
- should build my other thing first
- should do something

The invoke! method runs the task’s action(s) inside the spec’s instance, which means you can mock out methods and handle changes to instance variables.

Doesn’t much change my opinion of Rake, but at least I’ve got a better way to write tasks for it.

4 Responses to “Rake vs. RSpec! Fight!”

  1. Nolan Eakins Says:

    If I tossed this into a plugin of sorts, what can I license it under? PD? MIT? I’m sure I can throw in some matchers at some point. Perhaps you or some other serious gardeners could as well.

  2. Coda Says:

    Nolan– MIT, and go for it. I think it would make more sense as a gem; not every Rake task is in a Rails project.

  3. carolin Says:

    http://www.mobicue.com Mobicue is a social microblogging service. It allows users to update any photos, videos, or text and more in real time from their camera phones, and immediately shows them to friends on Mobicue. Mobicue encourages its users to invite and stay closer with their friends by sharing what they are up to instantly. The service also has a mobile client that supports all popular phones.

  4. Mike Breen Says:

    Very slick. Thank you.