How to RSpec your sidekiq-scheduler
Tags: rails, ruby, rspec, sidekiq
Published: 2020-07-04 13:07:39

---
title: How to RSpec your sidekiq-scheduler
published: true
description: How to test not only your code, but also yaml configuration files like sidekiq.yml
tags: rails, ruby, rspec, sidekiq
//cover_image: https://direct_url_to_image.jpg
---

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.

```ruby
# hello-scheduler.rbs
class HelloWorld < ApplicationJob
  def perform
    puts "Hello world"
  end
end
```

```yaml
# 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.

```rb
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.

```ruby
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.

```ruby
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.

```ruby
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.

```ruby
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!