怎样写rspec mailer测试

Contents
  1. Overview
  2. 准备工作
  3. 是否成功发送了email
  4. 是否成功将email发送到指定的接受者
  5. email的subject以及格式是否正确
  6. email是否由正确的地址发送

Overview

对于mailer的测试,主要针对以下四个方面:

  1. 是否成功发送了email;
  2. 是否成功将email发送到指定的接受者;
  3. email的subject以及格式是否正确;
  4. email是否由正确的地址发送?

准备工作

下面是我的mailer方法:

1
2
3
def confirmation_email(ordered_story)
mail(to: story.email, subject: "Here Is Your Story!", content_type: "text/html")
end

这是一个简单的确认邮件的mail。

在我的mailer spec中,首先配置ActionMailer,定义了在运行每个邮件测试前要做的事:

1
2
3
4
5
6
7
before(:each) do
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
@story = Factory.create(:story)
EbookConfirmationMailer.confirmation_email(@story).deliver
end

上述代码的意思是:

  1. 在test环境中发送email(必须明确指明);
  2. 应用到所有的发送请求;
  3. 创建发送列表;
  4. 使用Factory创建一个测试实例;
  5. 最后发送邮件。

接下来配置清空所有的发送项,确保运行每一个测试的时候干净的环境:

1
2
3
after(:each) do
ActionMailer::Base.deliveries.clear
end

配置工作完成!接下来开始写测试用例!

是否成功发送了email

1
2
3
it 'should send an email' do
ActionMailer::Base.deliveries.count.should == 1
end

在前面我创建了发送列表,所以在这个测试中,列表中应该只有一封邮件,并且在before的配置中只发送了一封邮件。

是否成功将email发送到指定的接受者

1
2
3
it 'renders the receiver email' do
ActionMailer::Base.deliveries.first.to.should == @story.email
end

Story类的实例有email的属性,对应了mailer方法中的 :to 。Story的工厂方法创建了一个带有email属性的实例,这个email属性就是在mailer中要发送的地址。

email的subject以及格式是否正确

1
2
3
it 'should set the subject to the correct subject' do
ActionMailer::Base.deliveries.first.subject.should == 'Here Is Your Story!'
end

如果邮件被成功发送,subject这一栏应该是我在mailer中定义的subject。

email是否由正确的地址发送

1
2
3
it 'renders the sender email' do
ActionMailer::Base.deliveries.first.from.should == ['[email protected]']
end

当我定义我的mailer时,我规定了邮件发送的默认地址 default :from => "[email protected]" ,与subject类似,如果邮件被成功发送,邮件中应该包含来源这一项。