TLDR; How can I test that a PORO argument for an asynchronous ActionMailer action (using Sidekiq) serializes and deserializes correctly?
Sidekiq provides RSpec matchers for testing that a job is enqueued and performing a job (with given arguments).
--
To give you some context, I have a Ruby on Rails 4 application with an ActionMailer. Within the ActionMailer is a method that takes in a PORO as an argument - with references to data I need in the email. I use Sidekiq to handle the background jobs. It turns out that there was an issue in deserializing the argument that it would fail when Sidekiq decided to perform the job. I haven't been able to find a way to test the correctness of the un/marshaling such that the PORO I called the action with is being used when performed.
For example:
Given an ActionMailer with an action
class ApplicationMailer < ActionMailer::Base
def send_alert profile
@profile = profile
mail(to: profile.email)
end
end
...
I would use it like this
profile = ProfileDetailsService.new(user)
ApplicationMailer.send_alert(profile).deliver_later
...
And have a test like this (but this fails)
let(:profile) { ProfileDetailsService.new(user) }
it 'request an email to be sent' do
expect {
ApplicationMailer.send_alert(profile).deliver_later
}.to have_enqueued_job.on_queue('mailers')
end
Any assistance would be much appreciated.
You can test it in a synchronous way (using only IRB and without the need of start the Sidekiq workers).
Let's say your worker class has the following implementation:
You can open IRB (
bundle exec irb
) and type the following commands:Thus, you will execute the code in a synchronous way AND using Sidekiq (note that we're invoking the
perform
method instead of theperform_async
).I think this is the best way to debug your code.