On Thu, Jan 27, 2011 at 10:30 AM, David Chelimsky <dchelim...@gmail.com> wrote: > > On Jan 27, 2011, at 7:48 AM, Michael Guterl wrote: > >> We have moved from Rails 2 to 3 and the changing Mailer syntax has >> caused us to rewrite some of our specs. >> >> In Rails 2: >> >> Implementation: >> Mailer.deliver_job_application(job.id, user.id) >> >> Spec: >> Mailer.should_receive(:deliver_job_application).with(@job.id, @user.id) >> >> --- >> >> In Rails 3: >> >> Implementation: >> Mailer.job_application(job.id, user.id).deliver >> >> Spec: >> message = double >> message.should_receive(:deliver) >> Mailer.should_receive(:job_application).with(@job.id, >> @user.id).and_return(message) >> >> --- >> >> I turned the latter example into a matcher for RSpec 2 and I'm open >> for feedback. >> >> Here's a gist incase the inline formatting sucks: >> https://gist.github.com/798513 >> >> RSpec::Matchers.define :deliver do |message| >> chain :with do |*args| >> @with = args >> end >> >> match do |mailer| >> mail = double >> mail.should_receive(:deliver) >> >> mailer.should_receive(message).with(*@with).and_return(mail) >> end >> end >> >> Mailer.should deliver(:job_application).with(@job.id, @user.id) >> >> --- >> >> Is this a sane approach? > > I think it's sane for inside your own app, but not as part of a lib. First, > it's bound to rspec-mocks, and including it in an rspec lib would require > extra handling to either make it only available for rspec-mocks or make it > support the other frameworks that rspec supports. Second, it hides a message > expectation. Again, that's fine for your own app, in which you know what's > going on, but would confuse some users if it were in a lib. > > Make sense? >
Once you confirmed my sanity, I started implementing this matching in the rest of the project. Everything was fine until I came to an example that negates the expectation with should_not. Mailer.should_not deliver(:job_application).with(@job.id, @user.id) Failure/Error: Mailer.should_not deliver(:job_application).with(@job.id, @user.id) expected Mailer not to deliver :candidate_abandon_message I can fix this by adding another matcher: RSpec::Matchers.define :not_deliver do |message| match do |mailer| mailer.should_not_receive(message).with(*@with) end end but this feels awfully hacky and unconventional. I know Capybara has to do something similar with has_content / has_no_content and I know my team (and myself) never seem to get this correct. Is there a better way to do this? Best, Michael Guterl _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users