使用 Ruby 3.2 使用关键字参数调用函数时获取错误数量的参数

Dan*_*cia 6 ruby rspec ruby-on-rails keyword-argument

我将项目中的 Ruby 版本从 2.7.3 更新到 3.2.0,一些测试开始失败。其中之一是使用关键字参数调用函数。这是它抛出的错误:

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)>'
Run Code Online (Sandbox Code Playgroud)

这是被调用函数的定义:

 class NotificationsMailer < ApplicationMailer

  VENDOR_SUPPORT_EMAIL = "vendor-support@saatvamattress.com"

  def notify(recipient_emails:, subject:, body:)
    @body = body
    @subject = subject
    mail(bcc: recipient_emails, subject: @subject, reply_to: VENDOR_SUPPORT_EMAIL)
  end

end

Run Code Online (Sandbox Code Playgroud)

这是测试文件:

require "rails_helper"

RSpec.describe NotificationsMailer, type: :mailer do
  describe 'notify' do
    let(:recipient_emails) { %w[test@mail.com test2@mail.com] }

    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 ['test@mail.com', 'test2@mail.com']
    end

    it 'Sets reply_to with vendor support email' do
      expect(mail.reply_to).to eq ['vendor-support@saatvamattress.com']
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我知道 ruby​​ 3 对关键字参数进行了一些更改,但是当我以相同的顺序使用参数调用函数并指定所有关键字时,我不知道问题出在哪里。

在一些线程之后,我尝试以散列形式发送参数以及其他一些不太有希望的事情,但仍然收到错误,不知道那里发生了什么。

Mik*_* A. 6

我能够使用 Rails 6.1.7.2 和 Ruby 3.2.1 重现您的问题。问题是 Rails 6.1 和 Ruby 3.2 不完全兼容。人们正在努力将 3.2 兼容性修复程序向后移植到 Rails 6.1(请参阅https://github.com/rails/rails/pull/46895),但它们似乎尚未发布。

您可以升级到较低版本的 Ruby(3.1.2 对我来说工作得很好,我相信 3.1.3 也可以),或者您可以将邮件程序代码更改为如下所示:

  def notify(recipient_emails, subject, body)
    [omitted]
  end
Run Code Online (Sandbox Code Playgroud)

(显然也改变了你调用该函数的方式)。

不过,在使用 Rails 6.1 和 Ruby 3.2 时,存在一些风险,即您会遇到更多与 kwargs 相关的问题,因此也许使用 Ruby 3.1 是更好的选择。