I got tripped up by this the other day - I was writing feature specs around resetting passwords, and my
PasswordReset interactor used
ActiveJob to send the password reset email asynchronously.
ActiveJob you could just access
ActionMailer::Base.deliveries and get at the message that had been generated, but that wasn’t working. After a bit of searching and some failed attempts at other approaches, I figured out what needed to be done.
.deliver_later queue up jobs to process later, you need to actually process the queue before you can access the email. To do this you need to first include
ActiveJob::TestHelper in your feature spec. This gives access to a few methods, but the one that we need is
perform_enqueued_jobs takes a block and performs any jobs in the
ActiveJob queue after the block has completed. We pass the
click_button "Reset Password" line in, and when that button is clicked the controller for password resets handles the process of generating the password reset email and putting it in to the queue. Without calling
perform_enqueued_jobs, that’s where it would sit, unprocessed and unavailable to our tests.
Since the queue is processed, the email is now available for us to access. In this case I am using the capybara-email gem to access the email and follow the link to it. From there everything continues as any normal feature spec would.
One weird thing that I encountered while doing this was that while including
ActiveJob::TestHelper at the top of the spec got it to pass, it broke a few other specs that were directly checking
ActiveJob::Base.queue_adapter.enqueued_jobs started to break because
ActiveJob::Base.queue_adapter was nil.
I haven’t investigated this much so far, but moving
include "ActiveJob::TestHelper" to
rails_helper.rb fixed it, so I’ve left it at that for now.