我有一个像这样的RSpec测试:
it "should ..." do
# mailer = mock
# mailer.should_receive(:deliver)
Mailer.should_receive(:notification_to_sender)#.and_return(mailer)
visit transactions_path
expect do
page.should_not have_css("table#transactions_list tbody tr")
find('#some_button').click
page.should have_css("table#transactions_list tbody tr", :count => 1)
end.to change{Transaction.count}.by(1)
end
如果我删除顶部的评论文件,测试通过。但随着评论部分的到位(我将如何编写它),测试失败了。
我在网上搜索了一些谷歌的评论文章,但我并不真正理解它在做什么,或者为什么要修复它。似乎应该有一种更简洁的方法来测试没有这个的电子邮件。
任何人都能解开一些光明吗?谢谢!
我使用的是rails 3和rspec-rails 2.10.1
答案 0 :(得分:2)
我认为您希望Mailer的实例接收notification_to_sender而不是类。来自Rails API
您永远不会实例化您的邮件程序类。相反,您的传递实例方法会自动包装在类方法中,这些方法以“deliver_”开头,后跟您要传递的邮件程序方法的名称。上面定义的signup_notification方法是通过调用Notifier.deliver_signup_notification来提供的。
因此我会使用
Mailer.any_instance.should_receive(:notification_to_sender)
此外,如果您需要获取最后发送的消息,请使用
ActionMailer::Base.deliveries.last
我认为这应该可以解决你的问题。
答案 1 :(得分:2)
您可能在控制器中调用Mailer.notification_to_sender.deliver
,或者更好的是,后台工作。我猜think_to_sender也可能需要一个参数。
无论如何,当您在Mailer上调用notification_to_sender
方法时,您将获得一个Mail::Message
的实例,其中包含deliver
方法。如果您只是在不调用Mailer.notification_to_sender
的情况下执行deliver
,那么您可以使用评论运行您拥有的内容,一切都会好的。我猜你也会打电话给deliver
。
在这种情况下,您的失败消息将类似于
NoMethodError:
undefined method `deliver' for nil:NilClass
这是因为nil
在很多时候都是Ruby的默认返回值,Rails也会继承它。如果没有指定mailer = mock
和.and_return(mailer)
部分,当控制器在测试的上下文中执行时,notification_to_sender将返回nil,控制器将尝试在该nil对象上调用deliver
。
您注释掉的解决方案是模拟notification_to_sender
的返回值(通常为Mail::Message
),然后期望在其上调用deliver
方法。