2013-11-14 21 views
25

Tôi đang phát triển một ứng dụng Rails 4 liên quan đến việc gửi/nhận email. Ví dụ: tôi gửi email trong quá trình đăng ký người dùng, nhận xét của người dùng và các sự kiện khác trong ứng dụng.Kiểm tra ActionMailer với rspec

Tôi đã tạo tất cả email bằng cách sử dụng tác vụ mailer và tôi đã sử dụng rspecshoulda để thử nghiệm. Tôi cần kiểm tra xem các thư có được nhận đúng cho người dùng thích hợp hay không. Tôi không biết cách kiểm tra hành vi.

Vui lòng chỉ cho tôi cách thử nghiệm ActionMailer sử dụng shouldarspec.

+14

Tại sao câu hỏi này lại bị đóng làm chủ đề? –

Trả lời

41

good tutorial về cách kiểm tra ActionMailer bằng RSpec. Đây là thực tế tôi đã theo dõi và nó đã không làm tôi thất bại.

Các hướng dẫn sẽ làm việc cho cả hai Rails 3 và 4.

Trong trường hợp các hướng dẫn trong liên kết ở trên phá vỡ, đây là những bộ phận liên quan:

Giả sử Notifier bưu phẩm và User mô hình sau:

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 

Và cấu hình thử nghiệm sau đây:

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

Những thông số kỹ thuật sẽ giúp bạn có những gì bạn muốn:

# 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 cho bài đăng blog ban đầu về chủ đề này.

+3

Nhưng điều đó sẽ không bắt gặp bất kỳ vấn đề gì nếu bạn, giả sử bắt một ngoại lệ từ User.send_instructions và gửi cho chính mình một email có ngoại lệ. Bạn chỉ cần kiểm tra nếu * bất kỳ * e-mail được gửi, không phải là một cụ thể của bạn. – Phillipp

+2

@Phillipp thực hiện một điểm tốt và nếu bạn muốn kiểm tra (các) thư cụ thể, 'ActionMailer :: Base.deliveries' là một mảng của các đối tượng' Mail :: Message'. Tham khảo [Mail :: Message API] (http://www.rubydoc.info/github/mikel/mail/Mail/Message). – janechii

+0

Đối với những người tự hỏi tại sao 'mock_model' không hoạt động: http://stackoverflow.com/a/24060582/2899410 – 707

Các vấn đề liên quan