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

Jim*_*dra 3 rspec ruby-on-rails actionmailer observer-pattern

我正在编写一个简单的注释观察器,无论何时创建新注释,它都会触发邮件程序.所有相关的代码都在这个要点: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
Run Code Online (Sandbox Code Playgroud)

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

zet*_*tic 8

对于上下文:

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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您要检查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
Run Code Online (Sandbox Code Playgroud)

为什么邮件程序在原始版本的规范中返回nil?

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