Hi there, I''m fairly new to RSpec, and DataMapper and I''m trying to write a controller spec for an index action that will include DM query chaining. Here is a very simplified version of the Controller#index I''m working on def index @widgets = Widget.all(:order => [ :name.asc ]) if params[:alpha] @widgets = @widgets.by_alpha(params[:alpha]) elsif params[:beta] @widgets = @widgets.by_beta(params[:beta]) end end I''m trying to write a spec for this and I''m struggling. It feels like it''ll be something uber simple but I''m just not getting it. describe "GET ''index''" do it "should be successful" do get :index response.should be_success end it "assigns all widgets as @widgets" do widgets = [Factory.stub(:widget), Factory.stub(:widget)] Widget.stub(:all) { [widgets] } get :index assigns(:widgets).should == [widgets] end #... end Any assistance would be greatly appreciated. Kind regards, Sid -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110318/3fb9566b/attachment.html>
Would you post the results of your spec? I''d like to see what you''re getting. I''m not familiar with DataMapper, but from an Active Record standpoint, the order clause does not look right. e.g. should be Square.all.order(:name) Try running the spec without the order clause in index (e.g. Widget.all) just to see if that works to rule out the order clause. You might have to do stub chain on Widget for all and then order. Everything else seems fine at quick glance. Brian -- Posted via http://www.ruby-forum.com/.
What problems are you running into? It appears that you should stub out Widget.all before all examples, unless you really want to hit the database. Ken 2011/3/18 Sid Wood <sidwood2 at gmail.com>> Hi there, > > I''m fairly new to RSpec, and DataMapper and I''m trying to write a > controller spec for an index action that will include DM query chaining. > > Here is a very simplified version of the Controller#index I''m working on > > > def index > @widgets = Widget.all(:order => [ :name.asc ]) > if params[:alpha] > @widgets = @widgets.by_alpha(params[:alpha]) > elsif params[:beta] > @widgets = @widgets.by_beta(params[:beta]) > end > end > > I''m trying to write a spec for this and I''m struggling. It feels like it''ll > be something uber simple but I''m just not getting it. > > describe "GET ''index''" do > it "should be successful" do > get :index > response.should be_success > end > > it "assigns all widgets as @widgets" do > widgets = [Factory.stub(:widget), Factory.stub(:widget)] > Widget.stub(:all) { [widgets] } > get :index > assigns(:widgets).should == [widgets] > end > > #... > end > > Any assistance would be greatly appreciated. > > Kind regards, > > Sid > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110318/c0ffcc5f/attachment-0001.html>
Thanks for the replies guys. My problem is writing a test for @widgets = @widgets.by_alpha(params[:alpha]) DataMapper allows you to chain additional criteria on an existing query and doesnt execute that query until in is used in the view. So the above statement gets baked into the previous default query @widgets Widget.all(:order => [ :name.asc ]). I''d just like to write a test that confirms the controller is in fact calling @widgets.by_alpha(params[:alpha]) when the params[:alpha] is present. Here is the code again so you don''t have to scroll to see it def index @widgets = Widget.all(:order => [ :name.asc ]) if params[:alpha] @widgets = @widgets.by_alpha(params[:alpha]) elsif params[:beta] @widgets = @widgets.by_beta(params[:beta]) end end Just to recap, this code is valid and works, I just don''t know how to write a test for it. Cheers, Sid -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110318/699e39d2/attachment.html>
When calling get/post/etc, the second optional parameter is a hash representing the "params" hash. So, in order to test the conditional(s) in your controller, you should write: get :index, :alpha => true #test the first conditional In another example, pass in :beta => true like this: get :index, :beta => true HTH, Ken 2011/3/18 Sid Wood <sidwood2 at gmail.com>> Thanks for the replies guys. > > My problem is writing a test for > > @widgets = @widgets.by_alpha(params[:alpha]) > > DataMapper allows you to chain additional criteria on an existing query and > doesnt execute that query until in is used in the view. So the above > statement gets baked into the previous default query @widgets > Widget.all(:order => [ :name.asc ]). > > I''d just like to write a test that confirms the controller is in fact > calling @widgets.by_alpha(params[:alpha]) when the params[:alpha] is > present. > > Here is the code again so you don''t have to scroll to see it > > > def index > @widgets = Widget.all(:order => [ :name.asc ]) > if params[:alpha] > @widgets = @widgets.by_alpha(params[:alpha]) > elsif params[:beta] > @widgets = @widgets.by_beta(params[:beta]) > end > end > > Just to recap, this code is valid and works, I just don''t know how to write > a test for it. > > Cheers, > > Sid > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110318/dfa6aba0/attachment.html>
Thanks Ken, but when I said I was new to RSpec I didn''t mean I was THAT new! ;o) I think people aren''t grasping the DataMapper chaining that is at the root of my testing confusion. I managed to come up with a solution that I''ve outlined here http://pastie.org/1690040 Basically, I mocked out a couple DataMapper::Collections and nested them. I''d love to hear if anyone would have tackled this issue differently. On 18 March 2011 18:01, Ken Chien <ken.chien at gmail.com> wrote:> When calling get/post/etc, the second optional parameter is a hash > representing the "params" hash. > > So, in order to test the conditional(s) in your controller, you should > write: > get :index, :alpha => true #test the first conditional > > In another example, pass in :beta => true like this: > get :index, :beta => true > > HTH, > Ken > > > 2011/3/18 Sid Wood <sidwood2 at gmail.com> > >> Thanks for the replies guys. >> >> My problem is writing a test for >> >> @widgets = @widgets.by_alpha(params[:alpha]) >> >> DataMapper allows you to chain additional criteria on an existing query >> and doesnt execute that query until in is used in the view. So the above >> statement gets baked into the previous default query @widgets >> Widget.all(:order => [ :name.asc ]). >> >> I''d just like to write a test that confirms the controller is in fact >> calling @widgets.by_alpha(params[:alpha]) when the params[:alpha] is >> present. >> >> Here is the code again so you don''t have to scroll to see it >> >> >> def index >> @widgets = Widget.all(:order => [ :name.asc ]) >> if params[:alpha] >> @widgets = @widgets.by_alpha(params[:alpha]) >> elsif params[:beta] >> @widgets = @widgets.by_beta(params[:beta]) >> end >> end >> >> Just to recap, this code is valid and works, I just don''t know how to >> write a test for it. >> >> Cheers, >> >> Sid >> >> _______________________________________________ >> 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 >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110319/e75066c3/attachment.html>
On 19 Mar 2011, at 17:49, Sid Wood wrote:> Thanks Ken, but when I said I was new to RSpec I didn''t mean I was THAT new! ;o) > > I think people aren''t grasping the DataMapper chaining that is at the root of my testing confusion. I managed to come up with a solution that I''ve outlined here http://pastie.org/1690040 > > Basically, I mocked out a couple DataMapper::Collections and nested them. I''d love to hear if anyone would have tackled this issue differently.Yes, I would have listened to the tests here, and heard that the interface to my model was awkward. I would either override Widget#all, or create a new method on the Widget that simply takes the params hash (or the three specific params new, name and materials) and figures out what to fetch from the database and returns it. You have data access concerns leaking out into your controller, which is why the interface is awkward to mock.> > > On 18 March 2011 18:01, Ken Chien <ken.chien at gmail.com> wrote: > When calling get/post/etc, the second optional parameter is a hash representing the "params" hash. > > So, in order to test the conditional(s) in your controller, you should write: > get :index, :alpha => true #test the first conditional > > In another example, pass in :beta => true like this: > get :index, :beta => true > > HTH, > Ken > > > 2011/3/18 Sid Wood <sidwood2 at gmail.com> > Thanks for the replies guys. > > My problem is writing a test for > > @widgets = @widgets.by_alpha(params[:alpha]) > > DataMapper allows you to chain additional criteria on an existing query and doesnt execute that query until in is used in the view. So the above statement gets baked into the previous default query @widgets = Widget.all(:order => [ :name.asc ]). > > I''d just like to write a test that confirms the controller is in fact calling @widgets.by_alpha(params[:alpha]) when the params[:alpha] is present. > > Here is the code again so you don''t have to scroll to see it > > > def index > @widgets = Widget.all(:order => [ :name.asc ]) > if params[:alpha] > @widgets = @widgets.by_alpha(params[:alpha]) > elsif params[:beta] > @widgets = @widgets.by_beta(params[:beta]) > end > end > > Just to recap, this code is valid and works, I just don''t know how to write a test for it. > > Cheers, > > Sid > > _______________________________________________ > 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 > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-userscheers, Matt matt at mattwynne.net 07974 430184 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110319/5c66ad2a/attachment-0001.html>
Thats great advice and now that you''ve pointed it out it seems so obvious. Thanks Matt. See you at Cukeup! Sid On 19 March 2011 22:11, Matt Wynne <matt at mattwynne.net> wrote:> > On 19 Mar 2011, at 17:49, Sid Wood wrote: > > Thanks Ken, but when I said I was new to RSpec I didn''t mean I was THAT > new! ;o) > > I think people aren''t grasping the DataMapper chaining that is at the root > of my testing confusion. I managed to come up with a solution that I''ve > outlined here http://pastie.org/1690040 > > Basically, I mocked out a couple DataMapper::Collections and nested them. > I''d love to hear if anyone would have tackled this issue differently. > > > Yes, I would have listened to the tests here, and heard that the interface > to my model was awkward. > > I would either override Widget#all, or create a new method on the Widget > that simply takes the params hash (or the three specific params new, name > and materials) and figures out what to fetch from the database and returns > it. You have data access concerns leaking out into your controller, which is > why the interface is awkward to mock. > > > > On 18 March 2011 18:01, Ken Chien <ken.chien at gmail.com> wrote: > >> When calling get/post/etc, the second optional parameter is a hash >> representing the "params" hash. >> >> So, in order to test the conditional(s) in your controller, you should >> write: >> get :index, :alpha => true #test the first conditional >> >> In another example, pass in :beta => true like this: >> get :index, :beta => true >> >> HTH, >> Ken >> >> >> 2011/3/18 Sid Wood <sidwood2 at gmail.com> >> >>> Thanks for the replies guys. >>> >>> My problem is writing a test for >>> >>> @widgets = @widgets.by_alpha(params[:alpha]) >>> >>> DataMapper allows you to chain additional criteria on an existing query >>> and doesnt execute that query until in is used in the view. So the above >>> statement gets baked into the previous default query @widgets >>> Widget.all(:order => [ :name.asc ]). >>> >>> I''d just like to write a test that confirms the controller is in fact >>> calling @widgets.by_alpha(params[:alpha]) when the params[:alpha] is >>> present. >>> >>> Here is the code again so you don''t have to scroll to see it >>> >>> >>> def index >>> @widgets = Widget.all(:order => [ :name.asc ]) >>> if params[:alpha] >>> @widgets = @widgets.by_alpha(params[:alpha]) >>> elsif params[:beta] >>> @widgets = @widgets.by_beta(params[:beta]) >>> end >>> end >>> >>> Just to recap, this code is valid and works, I just don''t know how to >>> write a test for it. >>> >>> Cheers, >>> >>> Sid >>> >>> _______________________________________________ >>> 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 >> > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > > > cheers, > Matt > > matt at mattwynne.net > 07974 430184 > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110320/5df75493/attachment.html>