London
London

Reputation: 15264

how to test sending emails to both recipients (Rspec)

Here is my test which is failing at the moment :

describe "User request update" do
    let(:user_one) { FactoryGirl.create(:user) }
    let(:user_two) { FactoryGirl.create(:user) }
    let(:mail) { UserMailer.notify_users(user_one, user_two) }  

    it "should notify both users" do
      mail.to.should include(user_one.email)
      mail.to.should include(user_two.email)
    end
  end

Here is my mailer bit :

def notify_users(requestor, user)
    [requestor, user].each{ |u| notify_user(requestor, u) }  
  end

def notify_user(requestor, user)
  @requestor = requestor
  @user = user
  mail :to => user.email, :subject => "User requested update"
end

How can I test is the mail being sent to both users?

Upvotes: 3

Views: 2515

Answers (1)

Jon
Jon

Reputation: 10898

Firstly you should ensure they have different email addresses.

Assuming your factory handles that (have you seen the Faker gem?) then you can test what was sent in the last sent message like this:

# The last email sent 
ActionMailer::Base.deliveries.last

You can check that the right number of messages were sent:

ActionMailer::Base.deliveries.count

So your test could look something like this:

describe "User request update" do
  let(:user_one) { FactoryGirl.create(:user) }
  let(:user_two) { FactoryGirl.create(:user) }
  # let(:mail) { UserMailer.notify_users(user_one, user_two) } 

  # If your method sends two separate emails:
  it "#notify_users should notify both users" do
    UserMailer.notify_users(user_one, user_two)
    expect(ActionMailer::Base.deliveries.count).to eq(2)
    expect(ActionMailer::Base.deliveries[0].to).to include(user_one.email)
    expect(ActionMailer::Base.deliveries[1].to).to include(user_two.email)
  end

  # If your method sends a single email with both recipients
  it "#notify_users should notify both users" do
    UserMailer.notify_users(user_one, user_two)
    expect(ActionMailer::Base.deliveries.count).to eq(1)
    expect(ActionMailer::Base.deliveries.last.to).to include(user_one.email)
    expect(ActionMailer::Base.deliveries.last.to).to include(user_two.email)
  end
end

You can make this a little nicer with some helper macros. Full details on how to do this are in this railscast:

http://railscasts.com/episodes/275-how-i-test

Upvotes: 7

Related Questions