sidekiq-scheduler is a pretty awesome tool to cron your sidekiq jobs. All you need is to add a schedule to your sidekiq.yml file.
Let's look at simple job with sidekiq-scheduler and yaml schedule itself.
# hello-scheduler.rbs
class HelloWorld < ApplicationJob
def perform
puts "Hello world"
end
end
# config/sidekiq.yml
:schedule:
hello_world:
cron: '0 0 * * * *' # Runs every hour
class: HelloWorld
But how you can test it to be sure that schedule does't have errors, cron syntax is correct and job class exists? You know that it's very easy to mess up your cron syntax! I will show and explain a snippet you can copy-paste to your project which will automatically check your sidekiq.yml file for errors.
Create file sidekiq_schedululer_spec.rb
in spec/jobs
folder. Sidekiq-scheduler uses fugit
under the hood to evaluate cron schedule. We will use it too, but for cron syntax checking. You don't need to add it in your Gemfile, because it's already included as a dependency in sidekiq-scheduler. The only thing is that you have to require it. Then we need to load our sidekiq.yml
file and parse it to ruby hash and store in schedule variable.
require "rails_helper"
require "fugit"
RSpec.describe "sidekiq-scheduler" do
sidekiq_file = File.join(Rails.root, "config", "sidekiq.yml")
schedule = YAML.load_file(sidekiq_file)[:schedule]
describe "cron syntax"
describe "job classes"
describe "job names" # optional
end
Here I defined three specs. We need to check that cron syntax (0 0 * * * *
) is correct, job class (HelloWorld
) exists and job name in schedule (hello_world
) is similar to job class.
First is cron. We just take every value in the file and pass it to Fugit
. If Fugit
raises error because it is not able to parse cron string, test fails.
describe "cron syntax" do
schedule.each do |k, v|
cron = v["cron"]
it "#{k} has correct cron syntax" do
expect { Fugit.do_parse(cron) }.not_to raise_error
end
end
end
Second, we need to check that job class exists. We just need to constantize our class string and if it raises error, test fails.
describe "job classes" do
schedule.each do |k, v|
klass = v["class"]
it "#{k} has #{klass} class in /jobs" do
expect { klass.constantize }.not_to raise_error
end
end
end
Third, we can check that job name (hello_world
) is similar to class name(HelloWorld
). It can be easily done by underscoring class name and compare it with job name.
describe "job names" do
schedule.each do |k, v|
klass = v["class"]
it "#{k} has correct name" do
expect(k).to eq(klass.underscore)
end
end
end
Full snippet is here. You can just copy and paste it in your project.
require "rails_helper"
require "fugit"
RSpec.describe "sidekiq-scheduler" do
sidekiq_file = File.join(Rails.root, "config", "sidekiq.yml")
schedule = YAML.load_file(sidekiq_file)[:schedule]
describe "cron syntax" do
schedule.each do |k, v|
cron = v["cron"]
it "#{k} has correct cron syntax" do
expect { Fugit.do_parse(cron) }.not_to raise_error
end
end
end
describe "job classes" do
schedule.each do |k, v|
klass = v["class"]
it "#{k} has #{klass} class in /jobs" do
expect { klass.constantize }.not_to raise_error
end
end
end
describe "job names" do
schedule.each do |k, v|
klass = v["class"]
it "#{k} has correct name" do
expect(k).to eq(klass.underscore)
end
end
end
end
This technique is usefull not only for sidekiq-scheduler. You can parse and test any yaml/json files in your projects in this way. Good luck with your RSpec experiments!
Top comments (3)
Just wanna mention, that sidekiq-scheduler support more options than
cron:
only: there is alsoevery:
,in:
,at:
. To not having failing specs you could add these options too:Have you tested cron job triggering?
so what I want to test:
if my job will be triggered on
may 5 2020 10:25:00 +0200
with my sidekiq cron:
what is the best way to do it?
Just created an account to comment this post because doesn't have any. Nice work dude!