2013-11-14 155 views
25

我正在开发一个Rails 4应用程序,其中涉及发送/接收电子邮件。例如,我在用户注册期间发送电子邮件,用户评论以及应用中的其他事件。使用rspec的ActionMailer测试

我创建使用动作mailer所有的电子邮件,我用rspecshoulda进行测试。我需要测试邮件是否被正确接收到正确的用户。我不知道如何测试行为。

请告诉我如何使用shouldarspec测试ActionMailer

+14

为什么地狱这个问题关闭作为题外话? –

回答

41

有关于如何使用RSpec测试ActionMailer的good tutorial。这是我遵循的做法,它并没有让我失望。

本教程将提供两个轨道3和4

如果在上面休息的链接教程,下面给出相关部分:

假设下面的Notifier邮件和User型号:

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 

和下面的测试配置:

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

这些规格应该得到你想要的东西:

# 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 

道具卢卡斯卡顿关于这一主题的原始博客文章。

+3

但是,如果你有任何问题,我们可以从User.send_instructions捕获一个异常,并向自己发送一封包含异常的电子邮件。你只是测试是否发送了*任何*电子邮件,而不是你特定的电子邮件。 – Phillipp

+2

@Phillipp提出了一个很好的观点,如果你想测试特定的邮件,ActionMailer :: Base.deliveries是一个包含'Mail :: Message'对象的数组。请参阅[Mail :: Message API](http://www.rubydoc.info/github/mikel/mail/Mail/Message)。 – janechii

+0

对于那些想知道为什么'mock_model'不起作用的人:http://stackoverflow.com/a/24060582/2899410 – 707