4

I'm using email_spec gem to test a simple email, but for some reason the body content appears to be empty:

  1) ContactMailer welcome email to new user renders the body
     Failure/Error: mail.should have_body_text("Hi")
       expected the body to contain "Hi" but was ""
     # ./spec/mailers/contact_mailer_spec.rb:17:in `block (3 levels) in <top (required)>'

Every other example passes. The template file is called welcome_email.text.erb. Not sure why body is not matched, but the email does have a body when it gets sent.

Edit: the Rspec code is:

let(:mail) { ContactMailer.welcome_email(email) }


it "renders the body" do
  mail.should have_body_text("Hi")
end
picardo
  • 24,530
  • 33
  • 104
  • 151

2 Answers2

9

The best way I've found to do this is:

it "contains a greeting" do
  mail.html_part.body.should match /Hi/
end

You can also use text_part in place of html_part if you want to check the plain text part of a multipart message.

Also note that others may recommend using #encoded, but I had trouble using that with long URLs, as they may get line-wrapped during the encoding process.

Matt Green
  • 2,032
  • 2
  • 22
  • 36
0

So, I was experiencing the same thing. I was trying to test my mailers without loading all of Rails.

What finally solved my problem was adding this to my test: (note that my test is in test/unit/mailers/my_mailer_test.rb - you may have to adjust paths)

ActionMailer::Base.delivery_method = :test
ActionMailer::Base.view_paths = File.expand_path('../../../../app/views', __FILE__)

Basically, without the view paths pointing to your views directory, the template is not found and all the parts (html, text, etc) are blank.

NOTE: The directory specified is NOT the one the actual templates are in. The mailer knows to look for a directory in the template root named after the class itself.

Here's a sample in minitest/spec

require 'minitest/spec'
require 'minitest/autorun'
require "minitest-matchers"
require 'action_mailer'
require "email_spec"

# NECESSARY TO RECOGNIZE HAML TEMPLATES
unless Object.const_defined? 'Rails'
  require 'active_support/string_inquirer'
  class Rails
    def self.env
       ActiveSupport::StringInquirer.new(ENV['RAILS_ENV'] || 'test')
    end
  end
  require 'haml/util'
  require "haml/template"
end
# END HAML SUPPORT STUFF

require File.expand_path('../../../../app/mailers/my_mailer', __FILE__)

ActionMailer::Base.delivery_method = :test
ActionMailer::Base.view_paths = File.expand_path('../../../../app/views', __FILE__)

describe MyMailer do
  include EmailSpec::Helpers
  include EmailSpec::Matchers

  let(:the_email){ MyMailer.some_mail() }

  it "has the right bit of text" do
    the_email.must have_body_text("some bit of text")
  end
end
Matt Van Horn
  • 1,654
  • 1
  • 11
  • 21