簡體   English   中英

如何避免使用 sendgrid-ruby 在 Rails test-env 中發送電子郵件?

[英]How to avoid sending emails in Rails test-env with sendgrid-ruby?

問題

我的 RSpec 測試似乎面臨一個頑固的問題,盡管我的配置應該避免它,但它試圖不斷地在 test-env 中發送電子郵件。 無論我嘗試什么,它似乎都完全忽略了它。

我的環境

  1. 軌道 6.1.1
  2. Ruby 3.0.0
  3. sendgrid-ruby gem 6.3.9

我有一個郵件程序 class 繼承鏈如下: OrganizationMailer <- ApplicationMailer <- ActionMailer::Base

在我的config/environments/test.rb我有以下與郵件相關的配置

config.action_mailer.delivery_method = :test
config.action_mailer.perform_deliveries = false
config.active_job.queue_adapter = :test

我的config/application.rbconfig/environment.rb不包含任何額外的配置。

也許有點離題,但以防萬一添加它:

我已確保ENV['RAILS_ENV'] ||= 'test'行存在spec/spec_helper.rbspec/rails_helper.rb ,因為出於某種原因 Rails 在暫存環境中隨機觸發了我的測試。 我還必須將項目中的.rspec文件內容從--require rspec_helper--require rails_helper 我從here1here2here3得到了解決方案。 但我認為這對當前的問題沒有任何作用。

糟糕的解決方案

我通過添加unless Rails.env.test? 每種電子郵件發送方法之上,我必須確保它們在測試中都不會到達 Sendgrid,但我知道這很糟糕。 這就是為什么我發布這個問題以在沒有這樣的 if/unless 子句的情況下正確修復這個問題。

我的理論

難不成是sendgrid-ruby惹的禍? 我從ApplicationMailerActionMailer繼承了東西,但最終發送電子郵件的是 Sendgrid ruby gem。 如果是這樣,如何最好地避免它? 我沒有從 sendgrid-ruby 文檔中找到任何關於此的提示。 我將在下面發布我的一個簡單的郵件程序方法,這樣您就可以看到 atm 的情況:

# frozen_string_literal: true

# using SendGrid's Ruby Library
# https://github.com/sendgrid/sendgrid-ruby
require 'sendgrid-ruby'

class MyMailer < ApplicationMailer
  include SendGrid

  def my_mailer_method(my_object:)
    unless Rails.env.test? # <---- Hack I'd like to get rid of
      from = Email.new(email: 'no-reply@my.domain', name: t('general.title'))
      to = Email.new(email: my_object.contact_email)
      subject = "#{t('my_mailer.my_mailer_method.subject')}: #{my_object.my_object_title}"

      content = Content.new(
        type: 'text/html',
        value: ApplicationController.render(
          template: 'my_mailer/my_mailer_method',
          locals: {
            my_object: my_object
          },
          layout: nil
        )
      )

      mail = SendGrid::Mail.new(from, subject, to, content)
      sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])

      # Send out mail
      response = sg.client.mail._('send').post(request_body: mail.to_json)
    end
  end
end

這里的問題是您可能已經設置了config.action_mailer.delivery_method =:test但您實際上並沒有使用 ActionMailer 來發送電子郵件。 相反,在 MyMailer class 中,您直接使用 SendGrid API,並完全回避 ActionMailer。

如果您想使用 SendGrid API 發送電子郵件,那么我實際上建議您使用sendgrid-actionmailer gem 它允許您使用 ActionMailer 來構建您的電子郵件,並使用引擎蓋下的 SendGrid API 來發送它們。 這允許您發送 API 支持的其他參數,而使用 SMTP 會更加困難或不可能,同時仍然使用Rails 標准 ActionMailer發送電子郵件。

為確保您的郵件在生產環境中由 SendGrid 發送,但在測試環境中不發送,您可以設置:

config.action_mailer.delivery_method = :sendgrid_actionmailer

在您的production.rb環境中。 並設置:

config.action_mailer.delivery_method = :test
config.action_mailer.perform_deliveries = false

正如您在test.rb環境中已有的那樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM