Home > Back-end >  Testing ActionMailer with both paramaters and arguments
Testing ActionMailer with both paramaters and arguments

Time:07-31

How do you test a mailer method that uses both params and arguments.

class UserMailer < ActionMailer::Base
  def invoice(invoice)
    @user = params[:user]
    ...
  end
end

None of these assertions will work:

  assert_enqueued_email_with UserMailer.with(user), :invoice, args: { invoice }
  assert_enqueued_email_with UserMailer.with(user), :invoice, args: [ user, invoice ]
  assert_enqueued_email_with UserMailer.with(user), :invoice, params: { user: user }, args: [ invoice ]

CodePudding user response:

You can check enqueued job

It's not so elegant like assert_enqueued_email_with but this method can't access parameters as arguments

UserMailer.with(user: user).invoice(invoice).deliver_later

job_args = ActiveJob::Base.queue_adapter.enqueued_jobs[0][:args]

assert_equal job_args.first, "UserMailer"
assert_equal job_args.second, "invoice"
assert_equal job_args.fourth["params"]["user"], user
assert_equal job_args.fourth["args"], [invoice]

There is also assert matcher for enqueued job. And it's possible to check ActionMailer::MailDeliveryJob with array of 4 arguments and passing mailer delivery to the block

assert_enqueued_with(job: ActionMailer::MailDeliveryJob, args: ["UserMailer", "invoice", "deliver_now", { params: { user: user }, args: [invoice] }], queue: "default") do
  UserMailer.with(user: user).invoice(invoice).deliver_later
end
  • Related