I have a rake task test that I setup following the only examples I could find online.
It looks like this:
require 'test_helper'
require 'minitest/mock'
require 'rake'
class TestScrapeWelcome < ActiveSupport::TestCase
def setup
Rake.application.init
Rake.application.load_rakefile
@task = Rake::Task['scrape:scrape']
@task.reenable
end
def teardown
Rake::Task.clear
end
test "scraping text and sending to elasticsearch" do
mocked_client = Minitest::Mock.new
get_fixtures.each_with_index do |arg,i|
mocked_client.expect :index, :return_value, [index: "test", type: 'welcome', id: i, body: arg]
end
Elasticsearch::Model.stub :client, mocked_client do
@task.invoke
end
assert mocked_client.verify
end
private
def get_fixtures
(0..11).map { |i|
File.read("test/fixtures/scrape/index_#{i}.json")
}
end
end
But after the task runs once it starts running again without me doing anything (puts
prints before and after @task.invoke
show that the task is only run the once).
I've tried @iheggie answer but it worked in a way that indeed tests were run once but any other task was breaking with
Don't know how to build task '<task_name_like_db_migrate>'
.I'm on Rails 3.2 still. It turned out that there were couple tasks loaded beforehand so the
Rake::Task.tasks.empty?
was nevertrue
and all other useful tasks were not loaded. I've fiddled with it and this version of it works for me right now:Hope this helps anyone.
A solution that works for testing the tasks of a Gem that has been made a
Railtie
so it can add tasks to the Rails app:Don't define the
Railtie
in test mode when you're also defining aRails::Application
class inspec_helper.rb
(which allows your tests to callRails.application.load_tasks
). Otherwise the Rake file will be loaded once as a Railtie and once as an Engine:Another solution would be to put a condition in the Rake file to skip the task definitions if the file has already been loaded.
Updated answer for rails 5.1 (using minitest):
I found I needed the following to load tasks once and only once:
Alternatively add
MyAppName::Application.load_tasks
to your test_helper, if you don't mind tasks being loaded even when running individual tests that don't need them.(Replace MyAppName with your application name)
Turns out that rake is already required and initialized when the test runs so all of the following lines need to be removed or the task gets defined twice and runs twice even if you only invoke it once.