On Dec 12, 2007 9:48 PM, Kyle Hargraves <[EMAIL PROTECTED]> wrote: > > On Dec 12, 2007 9:09 PM, Rick DeNatale <[EMAIL PROTECTED]> 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)
Not only could it support this, it DOES. That said, I'd go for a lesser known feature: custom mock argument matchers. Something like this (completely off the top of my head and not tested or guaranteed bug-free - but this will give you the idea): class EquivalentMessage def initialize(message) @message = message end def ==(other) other.subject == @message.subject && other.body == @message.body && other.sender == @message.sender && other.recipient == @message.recipient end end def message_equivalent_to(message) EquivalentMessage.new(message) end 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_equivalent_to(Message.new(msg_creation_parms))) Message.create(msg_creation_parms) end Try that out and see what you think. Cheers, David > > Feels clunky, though. > > Kyle > > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users