Rake tasks in RSpec

I built a Rake task the other day to strip off all leading and trailing whitespace in some database fields. Here is a simplified version of the code I wrote to do this.
namespace :household do
desc "Remove leading and trailing whitespace of records in the Item table"
task :strip_whitespace  => [:environment] do
Item.all.each do |item|
item.title = item.title.strip
item.description = item.description.strip
item.save
end
end
end
end

Although this is a pretty straightforward task, I thought it would be a good idea to test it before unleashing it upon a production database.

I found two blog posts that describe how to write tests for Rake tasks using the excellent RSpec framework:
one by Nick Sieger and one by Phil Sergi. Both give a somewhat different approach, but unfortunately none of them seemed to work for me. However, by combining the ideas described in these posts I got a working solution.

First I made sure to include the proper helper files.
require 'spec/spec_helper.rb'
require 'rake'

The next step was to define a before hook that sets up an instance of the Rake application in the test script.
before(:each) do
@rake = Rake::Application.new
Rake.application = @rake
load RAILS_ROOT + '/lib/tasks/strip_whitespace.rake'
Rake::Task.define_task(:environment)
end

The line
load RAILS_ROOT + '/lib/tasks/strip_whitespace.rake'
tells RSpec where it can find the implementation of the Rake task. In this case it’s in the file strip_whitespace.rake that resides in the default tasks folder of my Rails application.

After each test the instance of the Rake::Application class should be deleted, so the next test can start with a shiny new instance. The following after hook takes care of this.
after(:each) do
Rake.application = nil
end

Finally, I defined a procedure that performs the Rake task at my command.
def invoke_task
@rake["household:strip_whitespace"].invoke
end

And there it is. Now I was able to run the Rake task from within my tests like so:
it "should remove the leading and trailing in the title of each item" do
invoke_task
Item.all.each do |item|
item.title.should == item.title.strip
end
end

To put it all together, here is the complete code listing.
require 'spec/spec_helper.rb'
require 'rake'
describe "household:strip_whitespace task" do
before(:each) do
@rake = Rake::Application.new
Rake.application = @rake
load RAILS_ROOT + '/lib/tasks/strip_whitespace.rake'
Rake::Task.define_task(:environment)
end
after(:each) do
Rake.application = nil
end
def invoke_task
@rake["household:strip_whitespace"].invoke
end
it “should remove the leading and trailing in the title of each item” do
invoke_task
Item.all.each do |item|
item.title.should == item.title.strip
end
end
# …
end

Posted April 29th, 2009 by Lukas Spee
Tagged with: , ,
 

Comments

 
  1. [...] à cet article (et ceux cités dedans !), je peux tester une tâche rake avec [...]