7
votes

I have a rake task that calls abort if a condition is met, this is a simplified example:

name :foo do
  desc 'Runs on mondays'
  task bar: :environment do
    abort unless Date.current.monday?
    # do some special stuff
  end
end

When I write RSpec tests for this rake task, for the test case where the code aborts it causes the rest of the tests not to run.

My question is: in the tests is it possible to "stub" the abort in some way so it continues to run the other tests, or do I have no choice but to use another method to exit the rake task (such as next) and remove the abort altogether?

Edit

Here's a pseudo-ish code example of the test I'm working with. In my real test file I had other tests, and once this test would run it would abort and not run the others.

require 'rails_helper'
require 'rake'

RSpec.describe 'FooBar', type: :request do
  before { Rake.application.rake_require "tasks/foo" }

  it "doesn't foo the bar on Mondays" do
    allow(Date.current).to receive(:monday?).and_return(true)
    Rake::Task['foo:bar'].execute
    # expect it not to do the stuff
  end
end

In the end I just changed it to next instead of abort but I couldn't find an answer to this question on SO or by googling so I thought I'd ask.

1
Can you add a part of your test, mainly where your invoke your task? Do you call it once in a before each?morissetcl
@morissetcl added an example, but I'm not sure how helpful it is in answering the question. I tried a number of different invocations based on some research I did on testing rake tasks, they all had the same problem (which seems obvious now looking back on it). But I still was curious if I could avoid it aborting the test suite or not, or if I just have to always avoid abort in a rake task that I want to test.kaydanzie

1 Answers

1
votes

I know this is an old one, but I've been looking into this and I think the best way to get round this is by using raise_error. In your example this would look like:

require 'rails_helper'
require 'rake'

RSpec.describe 'FooBar', type: :request do
  before { Rake.application.rake_require "tasks/foo" }

  it "doesn't foo the bar on Mondays" do
    allow(Date.current).to receive(:monday?).and_return(false)
    expect { Rake::Task['foo:bar'].execute }.to raise_error(SystemExit)
  end
end

If you abort with a particular error for example:

name :foo do
  desc 'Runs on mondays'
  task bar: :environment do
    abort "This should only run on a Monday!" unless Date.current.monday?
    # do some special stuff
  end
end

You can test for the message too, i.e:

require 'rails_helper'
require 'rake'

RSpec.describe 'FooBar', type: :request do
  before { Rake.application.rake_require "tasks/foo" }

  it "doesn't foo the bar on Mondays" do
    allow(Date.current).to receive(:monday?).and_return(false)
    expect { Rake::Task['foo:bar'].execute }.to raise_error(SystemExit, "This should only run on a Monday!") # The message can also be a regex, e.g. /This should only run/
  end
end

Hope this helps future Googlers!