Je voudrais tester si un e-mail est envoyé si j'appelle une méthode de contrôleur avec: post. Je vais utiliser email_spec donc j'ai essayé ceci coupé ici: http://rubydoc.info/gems/email_spec/1.2.1/file/README.rdoc#Testing_In_Isolation
Mais cela ne fonctionne pas, car je passe une instance de l'objet-modèle à la méthode de livraison et l'instance est enregistrée avant la livraison.
J'ai essayé de créer une autre instance de l'objet-modèle, mais l'ID n'est pas le même.
Ma méthode de contrôleur ressemble à ceci:
def create
@params = params[:reservation]
@reservation = Reservation.new(@params)
if @reservation.save
ReservationMailer.confirm_email(@reservation).deliver
redirect_to success_path
else
@title = "Reservation"
render 'new'
end
end
Avez-vous une idée pour résoudre ce problème?
En supposant que votre environnement de test est configuré de la manière habituelle (c'est-à-dire que vous avez config.action_mailer.delivery_method = :test
), puis les e-mails envoyés sont insérés dans le tableau global ActionMailer::Base.deliveries
comme Mail::Message
les instances. Vous pouvez lire cela dans votre scénario de test et vous assurer que l'e-mail est conforme à vos attentes. Voir ici .
Configurez votre environnement de test pour accumuler les e-mails envoyés dans ActionMailer::Base.deliveries
.
# config/environments/test.rb
config.action_mailer.delivery_method = :test
Ensuite, quelque chose comme ça devrait vous permettre de tester que le courrier a été envoyé.
# Sample parameters you would expect for POST #create.
def reservation_params
{ "reservation" => "Drinks for two at 8pm" }
end
describe MyController do
describe "#create" do
context "when a reservation is saved" do
it "sends a confirmation email" do
expect { post :create, reservation_params }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
end
end
Notez que mon exemple utilise la syntaxe RSpec 3.
Je sais que je suis en retard à la fête avec celui-ci, mais pour les futurs Googlers ...
Je pense qu'une meilleure solution à ce problème est répondue ici
La réponse précédemment acceptée teste le Mailer lui-même (à l'intérieur des spécifications du contrôleur). Tout ce que vous devriez tester ici, c'est que le Mailer est invité à livrer quelque chose avec les bons paramètres.
Vous pouvez ensuite tester le Mailer ailleurs pour vous assurer qu'il répond correctement à ces paramètres.
ReservationMailer.should_receive (: confirm_email) .with (an_instance_of (Reservation))
Pour mémoire, à toute personne utilisant rspec 3.4 et ActiveJob pour envoyer des e-mails asynchrones, vous pouvez vérifier cela avec:
expect {
post :create, params
}.to have_enqueued_job.on_queue('mailers')
Voici comment tester que Mailer est appelé avec les bons arguments. Vous pouvez utiliser ce code dans les spécifications de fonctionnalité, de contrôleur ou de mailer:
delivery = double
expect(delivery).to receive(:deliver_now).with(no_args)
expect(ReservationMailer).to receive(:confirm_email)
.with('reservation')
.and_return(delivery)
Pour en ajouter un peu plus, assurez-vous que si vous voulez bloquer un appel à l'aide de should_receive, vous avez un test d'intégration ailleurs testant que vous appelez réellement la méthode correctement.
J'ai été un peu plusieurs fois en changeant une méthode qui a été testée ailleurs avec should_receive et en ayant toujours des tests réussis lorsque l'appel de méthode a été rompu.
Si vous préférez tester le résultat plutôt que d'utiliser should_receive, shoulda a un bon matcher qui fonctionne comme suit:
it { should have_sent_email.with_subject(/is spam$/) }
Plus d'informations sur l'utilisation des Matchers Shoulda avec rSpec
Si vous utilisez Capybara avec Capybara Email et vous avez envoyé un e-mail à [email protected]
, vous pouvez également utiliser cette méthode:
email = open_email('[email protected]')
Et puis vous pouvez le tester comme ceci:
expect(email.subject).to eq('SUBJECT')
expect(email.to).to eq(['[email protected]'])
Essayez email-spec
describe "POST /signup (#signup)" do
it "should deliver the signup email" do
# expect
expect(UserMailer).to(receive(:deliver_signup).with("[email protected]", "Jimmy Bean"))
# when
post :signup, "Email" => "[email protected]", "Name" => "Jimmy Bean"
end
end
plus d'exemples ici: https://github.com/email-spec/email-spec#testing-in-isolation