rspec-rails: expect { }.to have_enqueued_mail().with() doesn't work with ActionMailer::MailDeliveryJob

What Ruby, Rails and RSpec versions are you using?

Ruby version: 2.5.1 Rails version: 6.0.0 RSpec version: branch 4-0-dev

Observed behaviour

Given an email enqueued with:

SomeMailer.with(object: foo, option: { amended: true }).some_method.deliver_later

I would expect the following to pass:

expect { some_action_which_enqueues_mail }.to have_enqueued_mail(SomeMailer, :some_method).with(object: foo, option: { amended: true })

It doesn’t pass when setting the default delivery job to ActionMailer::MailDeliveryJob but does when using the legacy ActionMailer::Parameterized::DeliveryJob (ie. config.load_defaults 5.2 and Rails.application.config.action_mailer.delivery_job = 'ActionMailer::MailDeliveryJob' commented out in config/initializers/new_framework_defaults_6_0.rb

The listed enqueued mails shows the mail has been enqueued, but I cannot seem to access it with my test criteria.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 3
  • Comments: 35 (22 by maintainers)

Commits related to this issue

Most upvoted comments

You could work around it for now with a_hash_including("params" => a_hash_including("option" => "bar"))

For the future researchers, this have been fixed in various PRs (e.g. #2566) and released in 5.1.

Hi, I try the following workaround and it works on my project:

Ruby version: 2.6.5 Rails version: 5.2.4.1

RSpec::Rails::Matchers::HaveEnqueuedMail.define_method(:mailer_job) do
  ActionMailer::Parameterized::DeliveryJob
end

It seems that PR #2125 has resolved it but not released yet.

I’d imagine its because you tried replacing the method / args for the new Rails 6 style, but thats not the only style of args thats in use.

UnifiedMailer is a test class using ::ActionMailer::MailDeliveryJob

Something that needs to be added to the params building code in the matcher when Rails 6 is being used with this new mailer class