On Thu, Jan 27, 2011 at 10:30 AM, David Chelimsky <[email protected]> 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
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users