我正在开发一个依赖于许多自定义 Rake 任务的 ROR 应用程序。
测试它们的最佳方法是什么?
Rake 任务很难测试。最简单的解决方案是将逻辑移动到适当模型中的方法中。然后您可以对其进行测试,然后从 rake 任务中调用该方法。
就像是:
def execute_rake(file,task)
require 'rake'
rake = Rake::Application.new
Rake.application = rake
Rake::Task.define_task(:environment)
load "#{Rails.root}/lib/tasks/#{file}"
rake[task].invoke
end
根据您的规格:
execute_rake("tags.rake","tags:popular")
另一个 SO question很好地涵盖了这一点
我的建议,在这里总结一下,是不要尝试测试 rake 任务:将要测试的代码提取到类、模型或 lib 函数中并在那里进行测试。然后只需使用 rake 调用函数并管理依赖项。
我最喜欢PivotalLabs 的方式。但是,我在我的应用程序中概括并修改了他们的代码:
# file: spec/tasks/my_rake_file_spec.rb
require 'spec_helper'
require 'rake'
describe 'my_rake_file.rake' do
before :all do
Rake.application.rake_require 'tasks/my_rake_file'
Rake::Task.define_task(:environment)
end
let(:run_rake_task) {
Rake::Task[task_name].reenable
Rake.application.invoke_task task_name
}
describe 'my_task_name' do
let(:task_name) { "my_task_name" }
it "creates 10 cars" do
run_rake_task
Car.count.should == 10
end
end
end
另外,我将 my_rake_file.rake 的繁重代码提取到一个模块中,该模块存储在 lib/
好吧,现在有一个宝石:
Fantaskspec - https://github.com/crismali/fantaskspec
Rake 任务确实需要测试,特别是如果您在其中进行一些批处理。这些天来测试它们很容易:
class CleanExamsTaskTest < ActiveSupport::TestCase
def test_deletes_results_of_old_exams
travel_to Time.zone.parse('2010-07-05 10:00')
@exam.update!(end: Time.zone.parse('2010-07-04 09:59'))
assert_difference -> { @exam.answered_questions.count }, -1 do
capture_io { run_task }
end
end
def test_output
travel_to Time.zone.parse('2010-07-05 10:00')
@exam.update!(end: Time.zone.parse('2010-07-04 09:59'))
assert_output("Exams processed: 1\n") { run_task }
end
private
def run_task
Rake::Task['exams:clean'].execute
end
end
使用 Ruby >= 1.9 和 Rails 5.2 测试。从. Minitest
_ stdlib
没有其他依赖。