为触发邮件程序的观察者编写规范

时间:2011-02-16 19:05:58

标签: ruby-on-rails rspec observer-pattern actionmailer

我正在编写一个简单的注释观察器,无论何时创建新注释,它都会触发邮件程序。所有相关代码都在这个要点:https://gist.github.com/c3234352b3c4776ce132

请注意Notification的规范通过,但CommentObserver的规范失败,因为Notification.new_comment正在返回nil。我发现通过使用它可以获得通过规范:

describe CommentObserver do
  it "sends a notification mail after a new comment is created" do
    Factory(:comment)
    ActionMailer::Base.deliveries.should_not be_empty
  end
end

然而,这并不理想,因为它在观察者的规范中测试邮件程序的行为,而我真正想知道的是它正在触发邮件程序。为什么邮件程序会在原始版本的规范中返回nil?选择此类功能的最佳方法是什么?我正在使用Rails 3和RSpec 2(以及Factory Girl,如果这很重要的话)。

1 个答案:

答案 0 :(得分:8)

for context

class CommentObserver < ActiveRecord::Observer
  def after_create(comment)
    Notification.new_comment(comment).deliver
  end
end

# spec
require 'spec_helper'

describe CommentObserver do
  it "sends a notification mail after a new comment is created" do
    @comment = Factory.build(:comment)
    Notification.should_receive(:new_comment).with(@comment)
    @comment.save
  end
end

在这种情况下,您要检查通知上是否调用了deliver,这是期望应该去的地方。其余的规范代码用于设置期望并触发它。试试这种方式:

describe CommentObserver do
  it "sends a notification mail after a new comment is created" do
    @comment = Factory.build(:comment)
    notification = mock(Notification)
    notification.should_receive(:deliver)
    Notification.stub(:new_comment).with(@comment).and_return(notification)
    @comment.save
  end
end
  

为什么邮件发送者返回nil   规范的原始版本?

我认为这是因为消息期望就像存根一样 - 如果.and_return()中没有指定值或通过传入一个块,should_receive会返回nil