I have a couple rake tasks and I want to write specs for them. Yes, I should extract the programming logic from the rake tasks and encapsulate that logic into appropriate class methods. However this doesn't mean that I shouldn't be able to RSpec rake tasks.
I found an older post that got me 90% of the way to what I needed. The problem is that I suspect some sort of static file name caching is going on behind the scenes in rake so using #rake_require
in an RSpec context isn't performing the functionality I was expecting. I tried moving between before :all do
and before
blocks, nesting describe
blocks and all sorts of other craziness. I had 3 different specs and the first spec would always pass and the other two would fail; I could freely re-arrange the spec order and always the spec defined first would pass. This was maddening.
Turns out I just had to use load
instead of #rake_require
.
Here's what my now working spec ended up looking like, for the curious:
#./spec/lib/tasks/rake_tasks_spec.rb require 'spec_helper' require 'rake' describe "rake" do before do @rake = Rake::Application.new Rake.application = @rake # previously was trying # Rake.application.rake_require "tasks/get_comic" load Rails.root + 'lib/tasks/get_comic.rake' Rake::Task.define_task(:environment) end describe "task get_comic" do it "should have 'environment' as a prerequisite" do @rake['get_comic'].prerequisites.should include("environment") end it "works when expected input is received" do comic = Comic.new {|c| c.comic_id = 12} comic.should_receive(:save).and_return(true) result = Ilk::Parser::Result.new { |r| r.comic_id = 12 } result.should_receive(:to_model).and_return(comic) Ilk::Parser.should_receive(:parse).with(Ilk::Constants::COMIC_URL + '12').and_return(result) Comic.should_receive(:find_by_comic_id).with(12).and_return(nil) @rake['get_comic'].invoke('12') end it "raises an error when there was a problem parsing" do Ilk::Parser.should_receive(:parse).with(Ilk::Constants::COMIC_URL + '12').and_return(nil) -> { @rake['get_comic'].invoke('12') }.should raise_error end end end