Skip to content

Instantly share code, notes, and snippets.

@bigfive
Created January 7, 2014 08:14
Show Gist options
  • Save bigfive/8296139 to your computer and use it in GitHub Desktop.
Save bigfive/8296139 to your computer and use it in GitHub Desktop.
ActionMailer RSpec helpers. Makes mailer test more similar to controller tests in that you can test that instance variables are assigned for rendering
require "spec_helper"
describe ExampleMailer do
describe :new_user do
let(:user) { FactoryGirl.create :user }
it "sends to the correct addresses" do
# :mail is similar to the controller specs 'get', 'post' etc methods
mail :new_user, user
# :response is similar to controller specs, it returns the mail message
expect(response.from).to include 'from@example.com'
expect(response.to).to include 'to@example.com'
end
it "assigns @user" do
mail :new_user, user
# :assigns is similar to controller specs, it checks the view_assigns of the mailer renderer
expect(assigns(:user)).to eq user
end
end
end
module MailerHelpers
def mail(method, *arguments)
@_mail_called = true
@_mailer_method = method
@_mailer_arguments = arguments
end
def mailer
raise "You must use mail(:method_name) before calling :mailer" unless @_mail_called
@mailer ||= described_class.send :new, @_mailer_method, *@_mailer_arguments
end
def response
raise "You must use mail(:method_name) before calling :response" unless @_mail_called
@response ||= mailer.message
end
def assigns(method)
raise "You must use mail(:method_name) before calling :assigns" unless @_mail_called
mailer.view_assigns.with_indifferent_access[method]
end
end
RSpec.configure do |config|
config.include MailerHelpers, type: :mailer
end
@alexsanford
Copy link

This appears to be broken in Rails 5 😞

      Failure/Error: @mailer ||= described_class.send :new, @_mailer_method, *@_mailer_arguments

      ArgumentError:
        wrong number of arguments (given 3, expected 0)

@alexsanford
Copy link

Looks like this fixes it in Rails 5:

module MailerHelpers

  def mail(method, *arguments)
    @_mail_called = true
    @_mailer_method = method
    @_mailer_arguments = arguments
  end

  def mailer
    raise "You must use mail(:method_name) before calling :mailer" unless @_mail_called
    @mailer ||= described_class.new.tap do |mailer|
      mailer.process(@_mailer_method, *@_mailer_arguments)
    end
  end

  def response
    raise "You must use mail(:method_name) before calling :response" unless @_mail_called
    @response ||= mailer.message
  end

  def assigns(method)
    raise "You must use mail(:method_name) before calling :assigns" unless @_mail_called
    mailer.view_assigns.with_indifferent_access[method]
  end

end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment