53 votes

Rails - Comment testez-vous ActionMailer a envoyé un e-mail spécifique lors des tests

Actuellement dans mes tests, je fais quelque chose comme ça pour tester si un e-mail est mis en file d'attente pour être envoyé

 assert_difference('ActionMailer::Base.deliveries.size', 1) do       
  get :create_from_spreedly, {:user_id => @logged_in_user.id}
end
 

mais si l'action du contrôleur peut envoyer deux e-mails différents, c'est-à-dire un à l'utilisateur si l'inscription se passe bien ou une notification à l'administrateur en cas de problème - comment puis-je tester lequel a effectivement été envoyé. Le code ci-dessus passerait malgré tout.

83voto

todd Points 1410

Depuis les rails 3, ActionMailer :: Base.deliveries est un tableau de Mail :: Message. De la documentation de messagerie:

 #  mail['from'] = 'mikel@test.lindsaar.net'
#  mail[:to]    = 'you@test.lindsaar.net'
#  mail.subject 'This is a test email'
#  mail.body    = 'This is a body'
# 
#  mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
 

De là, il devrait être facile de tester vos e-mails dans une intégration

 mail = ActionMailer::Base.deliveries.last

assert_equal 'mikel@test.lindsaar.net', mail['from'].to_s

assert_equal 'you@test.lindsaar.net', mail['to'].to_s
 

31voto

Veger Points 17657

Lors de l'utilisation de la ActionMailer pendant les essais, tous les mails sont mis dans un grand tableau appelé deliveries. Ce que vous faites (et est suffisant pour la plupart) est de vérifier si les courriels sont présents dans le tableau. Mais si vous voulez contrôler en particulier pour un certain e-mail, vous devez savoir ce qui est réellement stocké dans le tableau. Heureusement, les e-mails se sont stockées, ainsi vous êtes en mesure de parcourir le tableau et vérifier chaque e-mail.

Voir ActionMailer::Base pour voir ce que les méthodes de configuration sont disponibles, que vous pouvez utiliser pour déterminer quels emails sont présents dans le tableau. Certaines des méthodes les plus efficaces pour votre cas sont probablement

  • recipients: Prend une ou plusieurs adresses e-mail. Ces adresses sont où votre e-mail sera livré. Jeux de le De: en-tête.
  • subject: Le sujet de votre email. Définit le Sujet: en-tête.

21voto

Neal Points 1594

En utilisant la syntaxe Rspec actuelle, j'ai fini par utiliser ce qui suit:

 last_email = ActionMailer::Base.deliveries.last
expect(last_email.to).to eq ['test@example.com']
expect(last_email.subject).to have_content 'Welcome'
 

Le contexte de mon test était une spécification de fonctionnalité où je voulais m'assurer qu'un e-mail de bienvenue était envoyé à un utilisateur après son inscription.

3voto

RyanWilcox Points 7838

Le framework de test devrait avoir un excellent assistant qui vous permet d'affirmer certaines conditions concernant un e-mail envoyé. Oui, vous pouvez le faire vous-même avec ActionMailer.deliveries, mais devrait tout faire en un petit bloc soigné

1voto

Brian Armstrong Points 8259

Ici est le meilleur moyen que j'ai trouvé pour le faire.

1) comprendre l' action mailer rappels plugin comme ceci:

script/plugin install git://github.com/AnthonyCaliendo/action_mailer_callbacks.git

Je n'ai pas vraiment utiliser le plugin principales fonctions, mais il fournit la fonctionnalité de nice d'être en mesure de comprendre la méthode qui a été utilisée pour envoyer un e-mail.

2) Maintenant, vous pouvez mettre quelques méthodes dans votre test_helper.rb comme ceci:

  def assert_sent(method_name)
    assert sent_num_times(method_name) > 0
  end

  def assert_not_sent(method_name)
    assert sent_num_times(method_name) == 0
  end

  def assert_sent_once(method_name)
    assert sent_num_times(method_name) == 1
  end

  def sent_num_times(method_name)
    count = 0
    @emails.each do |email|
      count += 1 if method_name == email.instance_variable_get("@method_name")
    end
    count
  end

3) Maintenant, vous pouvez écrire doux des tests de ce genre:

require 'test_helper'
class MailingTest < ActionController::IntegrationTest

  def setup
    @emails = ActionMailer::Base.deliveries
    @emails.clear
  end

  test "should send a mailing" do
    assert_difference "Mailing.count", 1 do
      feeds(:feed1).generate_mailing
    end

    assert_sent_once "broadcast"
    assert_not_sent "failed_mailing"
  end
end

Ici, la "diffusion" et "mailing_failed" sont les noms des méthodes, dans mon ActionMailer::la classe de Base. Ce sont ceux que vous utilisez habituellement en appelant Mailer.deliver_broadcast(some_data) ou Mailer.deliver_failed_mailing(some_data) etc. Ça y est!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X