views:

866

answers:

3

I have a series of rake tasks in a Rakefile which I'd like to test as part of my specs etc. Each task is defined in the form:

task :do_somthing => :environment do
  # Do something with the database here
end

Where the :environment task sets up an ActiveRecord/DataMapper database connection and classes. I'm not using this as part of Rails but I have a series of tests which I like to run as part of BDD.

This snippet illustrates how I'm trying to test the rake tasks.

def setup
  @rake = Rake::Application.new
  Rake.application = @rake
  load File.dirname(__FILE__) + '/../../tasks/do_something.rake'
end

should "import data" do
  @rake["do_something"].invoke
  assert something_in_the_database
end

So my request for help - is it possible to over-ride the :environment task in my test_helper.rb file so I my rake testing interacts with the my test database, rather than production? I've tried redefining the task in the helper file, but this doesn't work.

Any help for a solution would be great, as I've been stuck on this for the past week.

A: 

My "solution" to a similar problem was to extract all the logic from my .rake files and create classes to perform the tasks, leaving just a one-line call in the rake file, which I felt confident in not testing too hard. The classes could then be tested pretty much normally.

I don't know how well this would stand up to a complex set of interdependent tasks that maintain some far-reaching state: probably not well, but then again that would most likely be an indication of some other design problem...

I'm curious to see if I've missed something better.

EDIT: Here's a blog post that (a) says the same thing and (b) says it better. Looks like he said it first, too.

Mike Woodhouse
Thanks for your answer Mike. I've done some more messing around with Rake in the mean time, and I think these two methods in test_helper.rb might be some way towards a solution. def rake_up Rake.application = Rake::Application.new Rake::Task.define_task :environment Rake.application end def rake_down Rake.application = nil end
Michael Barton
A: 

when you are running tests environment is that is being loaded is test.

so you are interacting with test database only.

So i dont see any reason to override your rake task in test_helper.rb

Subba Rao
A: 

I think you are looking for this line: require(File.join(RAILS_ROOT, 'config', 'environment')) it's exactly what you find in "task :environment" implementation

I use it to test my rake tasks using rspec

Mateusz Juraszek