Problem
I seem to be facing a stubborn issue with my RSpec tests trying to constantly send emails in test-env despite my configuration should avoid it. Whatever I try it seems to totally ignore it.
My environment
- Rails 6.1.1
- Ruby 3.0.0
- sendgrid-ruby gem 6.3.9
I have a mailer class inheritance-chain as follows: OrganizationMailer
<-ApplicationMailer
<-ActionMailer::Base
In my config/environments/test.rb
I have the following mail-related configuration
config.action_mailer.delivery_method = :test
config.action_mailer.perform_deliveries = false
config.active_job.queue_adapter = :test
My config/application.rb
and config/environment.rb
don't contain any extra configuration.
Bit offtopic maybe, but just in case adding it as well:
I have ensured that the line ENV['RAILS_ENV'] ||= 'test'
is present in both- spec/spec_helper.rb
and spec/rails_helper.rb
since for some reason Rails randomly triggered my tests in staging environment. I also had to change the .rspec
file contents in my project from --require rspec_helper
to --require rails_helper
. I got the solution from here1, here2 and here3. But this I don't think plays any role in current problem.
Bad solution
I hacked my way through this issue atm by just adding the unless Rails.env.test?
on top of each email-sending method I'm having to ensure none of them reach Sendgrid in tests, but this sucks big time I know. That's why I'm posting this question to get this fixed properly without such if/unless-clauses.
My theory
Can it be that sendgrid-ruby is here to blame? I inherit things from ApplicationMailer
and ActionMailer
but eventually what is sending the emails is Sendgrid ruby gem. If so, how to avoid it best? I didn't find any hints from the sendgrid-ruby documentation about that. I will post one of my simple mailer-methods below so you could see the situation 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