web-dev-qa-db-fra.com

Test d'ActionMailer avec rspec

Je développe une application Rails 4 qui implique l'envoi/la réception d'e-mails. Par exemple, j'envoie des e-mails lors de l'inscription des utilisateurs, des commentaires des utilisateurs et d'autres événements dans l'application.

J'ai créé tous les e-mails à l'aide de l'action mailer, et j'ai utilisé rspec et shoulda pour les tests. Je dois tester si les mails sont reçus correctement aux bons utilisateurs. Je ne sais pas comment tester le comportement.

Veuillez me montrer comment tester un ActionMailer en utilisant shoulda et rspec.

32
Dinkaran Ilango

Il y a un bon tutoriel sur la façon de tester ActionMailer en utilisant RSpec. C'est la pratique que j'ai suivie et elle ne m'a pas encore échoué.

Le tutoriel fonctionnera pour les deux Rails 3 et 4.

Dans le cas où le tutoriel dans le lien ci-dessus se casse, voici les parties pertinentes:

En supposant que le modèle de courrier électronique Notifier et le modèle User suivants:

class Notifier < ActionMailer::Base
  default from: '[email protected]'

  def instructions(user)
    @name = user.name
    @confirmation_url = confirmation_url(user)
    mail to: user.email, subject: 'Instructions'
  end
end

class User
  def send_instructions
    Notifier.instructions(self).deliver
  end
end

Et la configuration de test suivante:

# config/environments/test.rb
AppName::Application.configure do
  config.action_mailer.delivery_method = :test
end

Ces spécifications devraient vous procurer ce que vous voulez:

# spec/models/user_spec.rb
require 'spec_helper'

describe User do
  let(:user) { User.make }

  it "sends an email" do
    expect { user.send_instructions }.to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end

# spec/mailers/notifier_spec.rb
require 'spec_helper'

describe Notifier do
  describe 'instructions' do
    let(:user) { mock_model User, name: 'Lucas', email: '[email protected]' }
    let(:mail) { Notifier.instructions(user) }

    it 'renders the subject' do
      expect(mail.subject).to eql('Instructions')
    end

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

    it 'renders the sender email' do
      expect(mail.from).to eql(['[email protected]'])
    end

    it 'assigns @name' do
      expect(mail.body.encoded).to match(user.name)
    end

    it 'assigns @confirmation_url' do
      expect(mail.body.encoded).to match("http://aplication_url/#{user.id}/confirmation")
    end
  end
end

Props à Lucas Caton pour le blog original sur ce sujet.

53
CDub