Testing rake tasks in Rails with RSpec
by mmyoji
1 min read
Suppose you have a posts:setup
task in lib/tasks/posts.rake
.
Prepare shared context
# spec/support/shared_contexts/rake.rb
shared_context "rake" do
# You define `task` inside your actual test example.
let(:rake_task) { Rake.application[task] }
before :all do
Rake.application = Rake::Application.new
Rake.application.rake_require(
self.class.top_level_description,
[Rails.root.join("lib", "tasks").to_s],
)
Rake::Task.define_task(:environment)
end
before do
rake_task.reenable
end
end
Ensure you have the following in your rails_helper.rb
or spec_helper.rb
, and
this will automatically load the above file.
# spec/rails_helper
Dir[Rails.root.join("spec", "support", "**", "*.rb")].each { |f| require f }
Actual Test file
There are three important parts with the shared_context
:
- Top level description
- task variable
rake_task.invoke
runs the task
# spec/lib/tasks/posts_spec.rb
require "rails_helper"
# 1. This must match the directory name
# where you define the rake task.
#
# e.g.)
# You want to test inside `lib/tasks/foo/bar/buz.rake`,
# and the top level description must be `"foo/bar/buz"`.
#
describe "posts" do
include_context "rake"
describe "setup" do
# 2. This must be the actual rake task name.
let(:task) { "posts:setup" }
it "will setup initial posts" do
# 3. and then `rake_task.invoke` executes the task.
expect { rake_task.invoke }.to change(Post, :count).by(3)
end
end
end
Thats it.