Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test html content generated by a Rails mailer?

I have come across a few tools that make it easier to test emails generated in a Rails app, but they are designed to be used in integration tests (i.e. capybara-email). However, I am writing a unit test that works directly with the mailer.

I currently have a test for my mailer that looks something like this:

RSpec.describe DigestMailer do
  describe "#daily_digest" do
    let(:mail) { DigestMailer.daily_digest(user.id) }
    let(:user) { create(:user) }

    it "sends from the correct email" do
      expect(mail.from).to eql ["[email protected]"]
    end

    it "renders the subject" do
      expect(mail.subject).to eql "Your Daily Digest"
    end

    it "renders the receiver email" do
      expect(mail.to).to eql [user.email]
    end

    it "renders the number of new posts" do
      expect(mail.body.raw_source).to match "5 New Posts"
    end
  end
end

However, I want to be able to test the html content a little easier than simply using regular expressions.

What I would really like to be able to do is something like this:

within ".posts-section" do
  expect(html_body).to have_content "5 New Posts"
  expect(html_body).to have_link "View More"
  expect(find_link("View More").to link_to posts_url
end

I don't know if there is a way to use Capybara directly to achieve something like this. Maybe there are alternatives that can provide similar functionality?

like image 674
Andrew Avatar asked Dec 08 '25 07:12

Andrew


1 Answers

According to this Thoughtbot article, you can convert a string to a Capybara::Node::Simple instance. This allows you to use capybara matchers against it.

I've created a helper method that uses this:

def email_html
  Capybara.string(mail.html_part.body.to_s)
end

Which I can then use as follows:

expect(email_html).to have_content "5 New Posts"
like image 128
keoghpe Avatar answered Dec 09 '25 21:12

keoghpe