Search code examples
ruby-on-railsrspecactionmailerrspec-rails

How can I test with RSpec that Rails 3.2 ActionMailer is rendering the correct view template?


I am using rspec-rails and I want to test that my mailer is rendering the correct view template.

describe MyMailer do
  describe '#notify_customer' do
    it 'sends a notification' do
      # fire
      email = MyMailer.notify_customer.deliver

      expect(ActionMailer::Base.deliveries).not_to be_empty
      expect(email.from).to include "[email protected]"

      # I would like to test here something like
      # ***** HOW ? *****
      expect(template_path).to eq("mailers/my_mailer/notify_customer")
    end
  end
end

Is this a valid approach? Or shall I do something completely different to that?

Update

MyMailer#notify_customer might have some logic (e.g. depending on the locale of the customer) to choose different template under different circumstances. It is more or less similar problem with controllers rendering different view templates under different circumstances. With RSpec you can write

expect(response).to render_template "....." 

and it works. I am looking for something similar for the mailers.


Solution

  • I think this is a step closer to the answer above, since it does test for implicit templates.

        # IMPORTANT!
        # must copy https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/support/helpers/next_instance_of.rb
        it 'renders foo_mail' do
          allow_next_instance_of(described_class) do |mailer|
            allow(mailer).to receive(:render_to_body).and_wrap_original do |m, options|
              expect(options[:template]).to eq('foo_mail')
    
              m.call(options)
            end
          end
    
          body = subject.body.encoded
        end