2010-12-07 141 views
3

我有在测试模式下使用Rails发送邮件略显奇怪的问题测试模式的ActionMailer发送电子邮件3在轨道3

看来,我的邮件程序不返回任何东西。例如,我有一个名为UserMailer的邮件程序。用户可以做出需要批准的应用程序的变化所以这也被称为changes_approved方法应该向用户发送一封电子邮件,通知他们,他们的变化已经approved.class

UserMailer < ActionMailer::Base 

    default :from => "[email protected]" 

    def changes_approved(user, page) 

    @user = user 
    @page = page 

    mail(:to => user.email, :subject => "Your changes have been approved") 

    end 

end 

在我的控制器我有以下行

UserMailer.changes_approved(@page_revision.created_by, @page_revision.page).deliver 

但是我的测试失败,在这一点上,出现错误:

未定义的方法'提供”的零:NilClass

当我在开发网站tho(http:// localhost:3000通过浏览器)触发相同的操作时,电子邮件被正确发送并且一切都很顺利

并且为了进一步增加混淆,我正在使用设计用于身份验证,而且在测试和开发模式下,这些电子邮件似乎都能正常工作。当然,我没有得到这个相同的错误,根据我的电子邮件规范测试,所有工作

因此,这导致我相信我有一个问题,什么。任何建议,将不胜感激

感谢

回答

1

好吧,我已经找到了答案,

它看起来像这个问题是我在测试这些邮寄的方式。在每个控制器测试我有类似

UserMailer.should_receive(:changes_approved).with(user, page) 

线虽然这个测试是路过精细,它的出现打破了邮件本身。我已经从测试中删除了这一行,现在他们通过了。对ActionMailer :: Base.deliveries.last的后续测试检查发送的电子邮件的详细信息是正确的,因此我很高兴看到这行不是必需的。

如果任何人有一个解释,为什么这打破寿,我很想找出

感谢反正

5

我有一个类似的问题 - 可能是UserMailer.changes_approved方法被换成了一个模拟方法,返回零(我没有使用应该进行该测试,但这是我最好的猜测)。

我的代码看起来像这样(修改为使用您的例子):

UserMailer.expects(:changes_approved).once 

我有一个额外的存根固定它:

@mailer = stub(:deliver) 
UserMailer.expects(:changes_approved).once.returns(@mailer) 

的无现正与@mailer取代。

2

要测试延迟动作邮件程序,我们需要首先更改delayed_job的配置(在config/initializers/delayed_job_config中。RB),以

Delayed::Worker.delay_jobs = !Rails.env.test? 

,并在测试中的预期应设置为

mock_mail = mock(:mail) 
mock_mail.should_receive(:deliver) 
UserMailer.should_receive(:changes_approved).with(user, page).and_return(mock_mail) 
+0

完美。谢谢。这正是你如何得到你的[RSpec](https://github.com/dchelimsky/rspec)+ [email_spec](https://github.com/bmabey/email-spec)+ [Delayed :: Job]( https://github.com/collectiveidea/delayed_job)规范传递。使用[无工作](https://github.com/lostboy/workless)根据需要在本地和Heroku上动态调整工作人员。 – chadoh 2011-05-14 14:02:26

10

我以前https://gist.github.com/1031144

# Rails 2 method: 
UserMailer.should_receive(:deliver_signup) 

转换为

# Cumbersome Rails 3 method: 
mailer = mock 
mailer.should_receive(:deliver) 
UserMailer.should_receive(:signup).and_return(mailer)