I updated the Ruby version from 2.7.3 to 3.2.0 in my project and some tests started to fail. Among those is one that is calling a function with keyword arguments. This is the error it's throwing:
1) NotificationsMailer notify Sets body
Failure/Error:
def notify(recipient_emails:, subject:, body:)
@body = body
@subject = subject
mail(bcc: recipient_emails, subject: @subject, reply_to: VENDOR_SUPPORT_EMAIL)
end
ArgumentError:
wrong number of arguments (given 1, expected 0; required keywords: recipient_emails, subject, body)
# ./app/mailers/notifications_mailer.rb:5:in `notify'
# /usr/local/bundle/gems/actiontext-6.1.6/lib/action_text/rendering.rb:20:in `with_renderer'
# /usr/local/bundle/gems/actiontext-6.1.6/lib/action_text/engine.rb:59:in `block (4 levels) in <class:Engine>'
# ./spec/mailers/notifications_mailer_spec.rb:16:in `block (3 levels) in <top (required)>'
This is the definition of the function being called:
class NotificationsMailer < ApplicationMailer
VENDOR_SUPPORT_EMAIL = "[email protected]"
def notify(recipient_emails:, subject:, body:)
@body = body
@subject = subject
mail(bcc: recipient_emails, subject: @subject, reply_to: VENDOR_SUPPORT_EMAIL)
end
end
And this is the test file:
require "rails_helper"
RSpec.describe NotificationsMailer, type: :mailer do
describe 'notify' do
let(:recipient_emails) { %w[[email protected] [email protected]] }
let(:mail) do
NotificationsMailer.notify(
recipient_emails: recipient_emails,
subject: 'subject',
body: 'body'
)
end
it 'Sets body' do
expect(mail.body.encoded).to match 'body'
end
it 'Sets subject' do
expect(mail.subject).to eq 'subject'
end
it "Does not set To" do
expect(mail.to).to be_nil
end
it "Does not set CC" do
expect(mail.cc).to be_nil
end
it "Sets BCC with recipients' emails" do
expect(mail.bcc).to eq ['[email protected]', '[email protected]']
end
it 'Sets reply_to with vendor support email' do
expect(mail.reply_to).to eq ['[email protected]']
end
end
end
I know ruby 3 introduced some changes to keyword arguments, but as I'm calling the function with the arguments in the same order and specifying all the keywords, I don't see where my problem is.
Following some threads I tried sending the arguments in a hash and some other things that weren't so promising, but still getting the error, no clue of what's happening there.
notify
is an instance method but you call it as a class method. This is where Rails comes into play – the (hidden) class method handles the instantiation and passing of arguments. The latter fails for keyword arguments. – MiscueNotificationsMailer.new.notify(...)
will also solve the problem and allow use of keyword arguments. – Debunk