[rspec-users] Setting expections on chained calls

Justin Ko jko170 at gmail.com
Tue Nov 8 10:01:15 EST 2011


On Nov 8, 2011, at 3:29 AM, Rob Aldred wrote:

> On Tue, Nov 08, 2011 at 12:36:22AM +0000, Justin Ko wrote:
>> 
>> On Nov 7, 2011, at 4:13 PM, Matt Wynne wrote:
>> 
>>> 
>>> On 7 Nov 2011, at 18:37, Justin Ko wrote:
>>> 
>>>> On Nov 2, 2011, at 12:01 PM, Rob Aldred wrote:
>>>> 
>>>>> 
>>>>> I'm pretty sure this has probably been discussed before.
>>>>> I'm using couchdb (couchrest_model)
>>>>> 
>>>>> When speccing my controller i want to set expectations that im calling my couch views correctly.
>>>>> The query interface has recently been updated to work very similar to ARel
>>>>> 
>>>>> This means i have to rewrite some of my specs.
>>>>> 
>>>>> Old call:
>>>>> 
>>>>> Exam.by_created_at_and_not_archived(:start_key => [@exam.created_at], :endkey => ['0'],:limit => 2)
>>>>> 
>>>>> I set an expectation on that easily like so:
>>>>> 
>>>>> Exam.should_receive(:by_created_at_and_not_archived).
>>>>>       with(:startkey => [@exam1.created_at],:endkey => ['0'],:limit => 2).
>>>>>       and_return([@exam1, at exam2])
>>>>> 
>>>>> However the new api i doesn't seem that easy to work with:
>>>>> 
>>>>> Exam.by_created_at_and_not_archived.startkey([@exam.created_at]).endkey(['0']).limit(2)
>>>>> 
>>>>> I could use stub_chain, but that doesn't allow me to check the params being passes to the calls other than the last.
>>>>> I could also create a wrapper method on my Exam model that is called from the controller with hash params,
>>>>> however that just shifts the problem, I then have to check the expections in the model spec instead.
>>>>> 
>>>>> Suggestions on how best to go about that would be appreciated.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> rspec-users mailing list
>>>>> rspec-users at rubyforge.org
>>>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>> 
>>>> Exam.should_receive(:by_created_at_and_not_archived).and_return(
>>>> double('startkey').tap {|startkey|
>>>>  startkey.should_receive(:startkey).with([@exam.created_at]).and_return(
>>>>    double('endkey').tap {|endkey|
>>>>      endkey.should_receive(:endkey).with(['0']).and_return(
>>>>        double('limit').tap {|limit|
>>>>          limit.should_receive(:limit).with(2).and_return([@exam1, @exam2])
>>>>        }
>>>>      )
>>>>    }
>>>>  )
>>>> }
>>>> )
>>>> 
>>>> LOL, this is the ugliest code I've written all year. You'd might want to use variables for readability:
>>> 
>>> ...or even wrap this Exam thing in an abstraction layer? Can anyone else hear the tests screaming?
>> 
>> Personally, I wouldn't mock this code at all. It's a data retrieval method, let it hit CouchDB (abstracted or not).
>> 
>>> 
>>> :)
>>> 
>>> cheers,
>>> Matt
>>> 
>>> --
>>> Freelance programmer & coach
>>> Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Hellesøy)
>>> Founder, http://relishapp.com
>>> +44(0)7974430184 | http://twitter.com/mattwynne
>>> 
>>> _______________________________________________
>>> rspec-users mailing list
>>> rspec-users at rubyforge.org
>>> http://rubyforge.org/mailman/listinfo/rspec-users
>> 
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
> 
> 
> Heh, that's magic.
> So maybe it's just better to create the documents in couch...
> I'm happy to do that, I just figured it would drastically effect performance of the tests.

Create the docs and test it in Isolation. If you're worried about performance, mock the abstracted method everywhere else.

> 
> Rob
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list