Job Spec
關於 Rails Active Job 請參考這篇文章 Active Job Basics。
Rails 的 Active Job 是一層內建的抽象,抽象了背景任務的執行,測試也非常容易撰寫。
以下介紹 Job 常見的測試標的。
命名慣例
spec/jobs/[job_name]_spec.rb
譬如:
app/jobs/application_job.rb
對應的測試文件為 spec/jobs/application_job_spec.rb
。
app/jobs/build_job.rb
對應的測試文件為 spec/jobs/build_job_spec.rb
。
文件結構
# app/jobs/application_job.rb
class ApplicationJob < ActiveJob::Base
end
# app/jobs/user_contact_sync_job.rb
class UserContactSyncJob < ApplicationJob
queue_as :low
def perform(user)
...
end
end
測試按 Job 內方法的撰寫順序來測:
# spec/jobs/user_contact_sync_job_spec.rb
require "rails_helper"
RSpec.describe UserContactSyncJob do
it "queue as" do
...
end
describe "#perform" do
...
end
end
require "rails_helper"
非常重要,這樣才會把 Rails 跟相關的設定(spec/rails_helper.rb
)都載入進來。
T> 測試的順序建議跟 Job 方法的順序相同,這樣當測試文件行數變多的時候,才容易找到測試的位置,讀程序的人也比較好讀。重點是要保持一致性。
要測什麼
個人建議將 Job 保持的越簡單越好,在 Job 只要檢查有正確傳遞消息,其餘的交給本來類別的單元測試。
- queue 的名稱
- 方法正確呼叫
以下是一個示例:
class UserContactSyncJob < ApplicationJob
queue_as :high
def perform(user)
UserContactSync.new(user).start
user.update(contact_refreshed: true)
end
end
require "rails_helper"
RSpec.describe UserContactSyncJob do
it "queue_as high" do
expect(UserContactSyncJob.new.queue_name).to eq("high")
end
describe "perform" do
it "syncs contacts and sets contact_refreshed to true" do
user = create(:user, contact_refreshed: false)
sync = double(:user_contact_sync, start: nil)
allow(UserContactSync).to receive(:new).and_return(sync)
UserContactSyncJob.perform_now(user)
expect(UserContactSync).to have_received(:new).with(user)
expect(sync).to have_received(:start)
expect(user.reload).to be_contact_refreshed
end
end
end
延伸閱讀
Rails 官方關於測試 Active Job 的文章:Testing Jobs。