[rspec-users] "Tricks" for testing after_create callback???

Kyle Hargraves philodespotos at gmail.com
Wed Dec 12 22:48:21 EST 2007


On Dec 12, 2007 9:09 PM, Rick DeNatale <rick.denatale at gmail.com> wrote:
> I've got a model Message, which needs to send an email using action
> mailer after it's first saved in the database.
>
> I want to pass the model to the mailer which then uses methods on the
> message model to render the email.
>
> So the natural way to do this is in an after_create callback on the
> Message model.
>
> But I can't see an easy way to test this. Here's my spec
>
> describe Message, "from anyone" do
>
>   it "should be sent on save" do
>     msg_creation_parms = {
>       :subject => "Subj",
>       :body => "hi",
>       :sender => people(:rick),
>       :recipient => people(:john)
>       }
>     SantasMailbox.should_receive(:deliver_secret_santa).with(Message.new(msg_creation_parms))
>     Message.create(msg_creation_parms)
>   end
>
> end
>
> This fails, but only because the model object has an id and time
> stamps assigned as it's saved.
>
> Spec::Mocks::MockExpectationError in 'Message from anyone should be
> sent on save'
> Mock 'Class' expected :deliver_secret_santa with (#<Message id: nil,
> subject: "Subj", body: "hi", sender_id: 343839476, recipient_id:
> 21341157, message_type: nil, created_at: nil, updated_at: nil>) but
> received it with (#<Message id: 1, subject: "Subj", body: "hi",
> sender_id: 343839476, recipient_id: 21341157, message_type: nil,
> created_at: "2007-12-12 21:53:16", updated_at: "2007-12-12 21:53:16">)
>
> I figured I'd through this out to the list for ideas on how best to
> approach this before I go to bed and sleep on it. <G>

Someone else may have a more elegant approach, but the block syntax to
should_receive() could allow something like:

expected_message = Message.new(msg_creation_params)
SantasMailbox.should_receive(:deliver_secret_santa) do |msg|
  msg.body.should == expected_message.body
  msg.subject.should == expected_message.subject
  # etc. if it's necessary
end
Message.create(msg_creation_params)

Feels clunky, though.

Kyle


More information about the rspec-users mailing list