Почему в моем тесте дважды запускается задача rake?
У меня есть тест с граблями, который я настроил, следуя единственным примерам, которые я смог найти в Интернете.
Это выглядит так:
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
Но после того, как задание запускается, оно снова запускается, и я ничего не делаюputs
печатает до и после @task.invoke
показать, что задача запускается только один раз).
3 ответа
Оказывается, что rake уже требуется и инициализируется при запуске теста, поэтому необходимо удалить все следующие строки или дважды определить задачу и выполнить дважды, даже если вы вызываете ее только один раз.
require 'minitest/mock'
require 'rake'
...
Rake.application.init
Rake.application.load_rakefile
Обновленный ответ для rails 5.1 (с использованием minitest):
Я обнаружил, что мне нужно следующее, чтобы загрузить задачи один раз и только один раз:
MyAppName::Application.load_tasks if Rake::Task.tasks.empty?
В качестве альтернативы добавьте MyAppName::Application.load_tasks
к вашему test_helper, если вы не возражаете против загрузки задач, даже если вы запускаете отдельные тесты, которые в них не нуждаются.
(Замените MyAppName именем вашего приложения)
Я пробовал ответ @iheggie, но он работал так, что тесты действительно запускались один раз, но любая другая задача ломалась с Don't know how to build task '<task_name_like_db_migrate>'
.
Я все еще использую Rails 3.2. Оказалось, что заранее была загружена пара задач, поэтомуRake::Task.tasks.empty?
никогда не был true
и все остальные полезные задачи не загружались. Я повозился с ним, и эта версия работает для меня прямо сейчас:
Rake::Task.clear if Rails.env.test?
MyAppName::Application.load_tasks
Надеюсь, это кому-нибудь поможет.
Решение, которое работает для тестирования задач Gem, который был сделан Railtie
поэтому он может добавлять задачи в приложение Rails:
Не определяйте Railtie
в тестовом режиме, когда вы также определяете Rails::Application
класс в spec_helper.rb
(что позволяет вашим тестам звонить Rails.application.load_tasks
). В противном случае файл Rake будет загружен один раз как Railtie и один раз как Engine:
class Railtie < Rails::Railtie
rake_tasks do
load 'tasks/mygem.rake'
end
end unless Rails.env.test? # Without this condition tasks under test are run twice
Другим решением было бы поместить условие в файл Rake, чтобы пропустить определения задач, если файл уже был загружен.