It can be a struggle to test Rails sometimes. Documentation surrounding the Rails ActiveJob module isn't the best. This post will walk you through some snippets and how you can test.
I use MiniTest as my primary testing framework but all code that are shown in these examples should also work for RSpec.
Asserting that something is enqueued in a Rails Test
test "sends one email and refreshes auth token" do
assert_enqueued_jobs(1) do
# Sends off an email
MailerServices::VerifyEmailEmailer.new(publisher: publisher).execute
end
end
Assert an email is enqueued
Another option is to check to see if an email sends correctly. You can view all the Test Helpers with ActionMailer::TestHelper
def test_emails
assert_emails 0
ContactMailer.welcome.deliver_now
assert_emails 1
ContactMailer.welcome.deliver_now
assert_emails 2
end
You can also check that a specific email was enqueued.
def test_email_in_block
assert_enqueued_email_with ContactMailer, :welcome do
ContactMailer.welcome.deliver_later
end
end
Test a specific job was enqueued
If your application enqueues a lot of jobs then you'll likely want to be more specific with your tests. Consider the following which asserts a specific job is enqueued.
test "create launches EnqueueUsersForPayoutJob for administrators" do
sign_in users(:admin)
assert_enqueued_with(job: EnqueueUsersForPayoutJob) do
post admin_payout_reports_path
end
end
You can even pass in arguments, so that you can ensure that something is valid
# Pull channel from fixtures
channel = channels(:unverified)
assert_enqueued_with(job: VerifySiteChannel, args: [{ channel_id: channel.id }]) do
# Execute job that enqueued VerifySiteChannel.
EnqueueSiteChannelVerifications.perform_now
end
Clear the existing jobs or queue
If you have a bunch of jobs in your ActiveJob queue then you might want to clear them out.
You can use clear_enqueued_jobs
which will reset the counter to 0. Later you can check assert_enqueued_jobs
increased.
test "approves channels that have waited the timeout period" do
clear_enqueued_jobs
clear_performed_jobs
travel(Channel::CONTEST_TIMEOUT + 1.minute) do
assert_enqueued_jobs 0
Channels::TransferChannelsJob.perform_now
assert_enqueued_jobs 1
end
end
Asserting how many jobs were performed
In the above example I'm asserting that jobs were enqueued, but what about jobs that were performed?
Consider the following code:
assert_performed_jobs 0
perform_enqueued_jobs(only: Promo::RegisterChannelForPromoJob)
assert_performed_jobs Promo::AssignPromoToChannelService::MAX_ATTEMPTS
We assert that there was 0 performed jobs. Then we execute only the job that we want to perform. Finally we assert that our retry logic in our job was valid. We do this by asserting the performed_jobs was equal to MAX_ATTEMPTS
.
Asserting or checking the performed jobs
Finally you can assert the performed job has the arguments you expect.
assert_performed_with(job: RegisterUserWithSendGridJob) do
patch(complete_signup_users_path, params: COMPLETE_SIGNUP_PARAMS)
end
Top comments (0)