2013-11-14 21 views
25

Zajmuję się tworzeniem aplikacji Rails 4, która obejmuje wysyłanie/odbieranie wiadomości e-mail. Na przykład wysyłam e-maile podczas rejestracji użytkownika, komentarza użytkownika i innych zdarzeń w aplikacji.Testowanie ActionMailer z rspec

Utworzyłem wszystkie wiadomości e-mail przy użyciu akcji mailer, a do testowania użyłem rspec i shoulda. Muszę sprawdzić, czy wiadomości są prawidłowo odbierane przez odpowiednich użytkowników. Nie wiem jak przetestować zachowanie.

Proszę pokazać, jak przetestować ActionMailer przy użyciu shoulda i rspec.

+14

Dlaczego do diabła jest to pytanie zamknięte jako nietypowe? –

Odpowiedz

41

Istnieje good tutorial o tym, jak przetestować ActionMailer za pomocą RSpec. Taką praktykę śledziłem i jeszcze mnie to nie zawiodło.

Tutorial będzie pracować dla obu szyn 3 i 4.

w przypadku samouczka w linku powyżej przerw, tutaj są odpowiednie części:

Zakładając następujące Notifier mailera i User modelu:

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 

A następującej konfiguracji testu:

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

Te specyfikacje powinien dostać to, co chcesz:

# 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 

podpory Lucas Caton do oryginalnego blogu na ten temat.

+3

Ale to nie przyniosłoby żadnych problemów, jeśli, powiedzmy, złap wyjątek od instrukcji User.send_instructions i wyślij e-mail z wyjątkiem. Po prostu przetestujesz, czy * żadna * wiadomość e-mail nie zostanie wysłana, a nie konkretna. – Phillipp

+2

@Phillipp przedstawił dobry punkt, a jeśli chcesz przetestować określoną pocztę (e), 'ActionMailer :: Base.deliveries' jest tablicą obiektów' Mail :: Message'. Zobacz [Mail :: Message API] (http://www.rubydoc.info/github/mikel/mail/Mail/Message). – janechii

+0

Dla tych, którzy zastanawiają się, dlaczego 'mock_model' nie działa: http://stackoverflow.com/a/24060582/2899410 – 707

Powiązane problemy