3

我有一个这样的 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

4

2 回答 2

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

我认为这应该可以解决您的问题。

于 2012-06-05T05:46:04.610 回答
2

你可能会调用Mailer.notification_to_sender.deliver你的控制器,或者更好的是,一个后台工作。我猜 notification_to_sender 可能也需要一个参数。

无论如何,当您在 Mailer 上调用该方法时,您将返回一个包含该方法notification_to_sender的实例。如果您只是在不调用的情况下进行操作,则可以在评论中运行您所拥有的内容,一切都会好起来的。我猜你也在打电话。Mail::MessagedeliverMailer.notification_to_senderdeliverdeliver

在这种情况下,您的失败消息将类似于

NoMethodError:
  undefined method `deliver' for nil:NilClass

这是因为nil大部分时间是 Ruby 的默认返回值,Rails 也继承了它。如果不指定mailer = mockand.and_return(mailer)部分,当控制器在测试上下文中执行时,notification_to_sender 将返回 nil 并且控制器将尝试调用deliver该 nil 对象。

您注释掉的解决方案是模拟出notification_to_sender的返回值(通常Mail::Message),然后期望deliver在其上调用该方法。

于 2013-06-13T03:48:18.277 回答