开发者

Writing a spec for an observer that triggers a mailer

开发者 https://www.devze.com 2023-02-10 17:50 出处:网络
I\'m writing a simple comment observer which triggers a mailer whenever a new comment is created. All the relevant code is in this gist: https://gist.github.com/c3234352b3c4776ce132

I'm writing a simple comment observer which triggers a mailer whenever a new comment is created. All the relevant code is in this gist: https://gist.github.com/c3234352b3c4776ce132

Note that the specs for Notification pass, but the specs for CommentObserver fail because Notification.new_comment is returning nil. I found that I could get a passing spec by using this instead:

describe CommentObserver do
  it "sends a notification mail after a new comment is created" do
    Factory(:comment)
    ActionMailer::Base.deliveries.should_not be_emp开发者_运维问答ty
  end
end

This is not ideal, however, because it tests the behavior of the mailer in the observer's spec, when all I really want to know is that it's triggering the mailer correctly. Why is the mailer returning nil in the original version of the spec? What is the best approach for speccing this type of functionality? I'm using Rails 3 and RSpec 2 (and Factory Girl, if that matters).


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

In this case you want to check that deliver is called on the Notification, so that's where the expectation should go. The rest of the spec code is there to set up the expectation and trigger it. Try it this way:

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

Why is the mailer returning nil in the original version of the spec?

I believe this is because message expectations act like stubs -- if no value is specified in .and_return() or by passing in a block, should_receive returns nil.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号