Ruby on rails 为什么我的rake任务在测试中运行了两次?
我有一个rake任务测试,我根据我能在网上找到的唯一例子来设置 看起来是这样的:Ruby on rails 为什么我的rake任务在测试中运行了两次?,ruby-on-rails,rake,minitest,rake-task,Ruby On Rails,Rake,Minitest,Rake Task,我有一个rake任务测试,我根据我能在网上找到的唯一例子来设置 看起来是这样的: require 'test_helper' require 'minitest/mock' require 'rake' class TestScrapeWelcome < ActiveSupport::TestCase def setup Rake.application.init Rake.application.load_rakefile @task = Rake::Ta
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
需要“测试助手”
需要“小型测试/模拟”
需要“耙子”
类TestScrapWelcome
但是在任务运行一次之后,它会在我不做任何事情的情况下再次开始运行(
将打印在@task.invoke
之前和之后,显示任务只运行一次).结果表明,在测试运行时,已经需要并初始化了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
添加到您的测试帮助器中,如果您不介意在运行不需要的单个测试时加载任务
(将MyAppName替换为您的应用程序名)一种解决方案,用于测试已成为Railtie
的Gem的任务,以便将任务添加到Rails应用程序:
当您还在spec\u helper.rb
中定义Rails::Application
类时,不要在测试模式中定义Railtie
(这允许您的测试调用Rails.Application.load\u任务
)。否则,Rake文件将加载一次作为Railtie,加载一次作为引擎:
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
class-Railtie
另一个解决方案是在Rake文件中设置一个条件,如果文件已经加载,则跳过任务定义。我尝试过@iheggie answer,但它的工作方式确实是测试运行一次,但任何其他任务都会中断,因为不知道如何构建任务“”
我仍然使用Rails 3.2。事实证明,之前加载了两个任务,因此Rake::Task.tasks.empty?
从来都不是true
,所有其他有用的任务都没有加载。我已经摆弄过了,现在这个版本对我很有用:
Rake::Task.clear if Rails.env.test?
MyAppName::Application.load_tasks
希望这对任何人都有帮助。如果您有任何添加rake任务的gem,这个答案将导致您的应用程序任务无法加载,因为rake::Task.tasks
此时不会为空。我使用的gem都需要显式添加到rake中,所以这对我来说很有用。您发现哪些gem会自动将其rake任务添加到应用程序中?如果是那样的话,你会怎么解决这个问题呢?杰瑞德咧嘴笑着说——我明白。我在Rails2.3.18LTS上仍然有一个客户端(他们可能永远都不会升级超过这个版本,因为他们没有预算在有免费LTS版本时进行更新)。不幸的是,最新的LTS版本不是免费的。我删除了以前的评论@iheggie指的是我在写的时候仍然使用Rails 3.2,这个解决方案对我来说是一个修复,即使使用了旧的Rails。不幸的是,事实证明,除了rake测试之外,没有其他任务在工作,所以让我们假设rake db:migrate失败了,因为rake不知道如何构建它。但我会更多地处理它,因为它是一个很好的跟踪,稍后我会发布我的发现。好的,对我来说,在Rails 3.2中,任务在那一点上不是空的,所以它从来没有工作过,只加载了现有的任务,它们是:default和:test。这意味着不会加载其他任务。我现在将发布我的解决方案,它实际上只是这个解决方案的一个版本。