[rspec-users] feedback on matcher

Michael Guterl mguterl at gmail.com
Thu Jan 27 14:07:35 EST 2011


On Thu, Jan 27, 2011 at 2:05 PM, Michael Guterl <mguterl at gmail.com> wrote:
> On Thu, Jan 27, 2011 at 10:30 AM, David Chelimsky <dchelimsky at 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
>

Please ignore the fact that the failure message
(candidate_abandon_message) is incorrect, I was adjusting my examples
for consistency.

Best,
Michael Guterl


More information about the rspec-users mailing list