Hi, I''m very new to rspec so please be patient with me. I''ve tried to take some of my tests out of the controller specs to check for things that are rendered. This has not worked so well, since my views have the controller method current_user in quite a few places. Is there any way that I can define this so that my views will be executed? Will this same thing occur for all helper methods that are definied in the controller? Cheers Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070705/1a8e6a3a/attachment.html
On 7/5/07, Daniel N <has.sox at gmail.com> wrote:> Hi, > > I''m very new to rspec so please be patient with me. > > I''ve tried to take some of my tests out of the controller specs to check for > things that are rendered. > > This has not worked so well, since my views have the controller method > > current_user > > in quite a few places. > > Is there any way that I can define this so that my views will be executed? > Will this same thing occur for all helper methods that are definied in the > controller?If I understand you correctly, you are trying to take tests for views that were previously rails functional tests and turn them into rspec view examples. If that is the case, you should be able to do this: template.stub!(:current_user).and_return(mock_model(User)) If not, please provide an explicit example so we can better understand what you''re talking about. Cheers, David> > Cheers > Daniel > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 7/6/07, David Chelimsky <dchelimsky at gmail.com> wrote:> > On 7/5/07, Daniel N <has.sox at gmail.com> wrote: > > Hi, > > > > I''m very new to rspec so please be patient with me. > > > > I''ve tried to take some of my tests out of the controller specs to check > for > > things that are rendered. > > > > This has not worked so well, since my views have the controller method > > > > current_user > > > > in quite a few places. > > > > Is there any way that I can define this so that my views will be > executed? > > Will this same thing occur for all helper methods that are definied in > the > > controller? > > If I understand you correctly, you are trying to take tests for views > that were previously rails functional tests and turn them into rspec > view examples. If that is the case, you should be able to do this: > > template.stub!(:current_user).and_return(mock_model(User)) > > If not, please provide an explicit example so we can better understand > what you''re talking about. > > Cheers, > DavidThanx David, That looks like what I was looking for. I will try it when I get home. Cheers Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070706/d0825410/attachment.html
On 7/6/07, Daniel N <has.sox at gmail.com> wrote:> > > > On 7/6/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > On 7/5/07, Daniel N <has.sox at gmail.com> wrote: > > > Hi, > > > > > > I''m very new to rspec so please be patient with me. > > > > > > I''ve tried to take some of my tests out of the controller specs to > > check for > > > things that are rendered. > > > > > > This has not worked so well, since my views have the controller method > > > > > > current_user > > > > > > in quite a few places. > > > > > > Is there any way that I can define this so that my views will be > > executed? > > > Will this same thing occur for all helper methods that are definied in > > the > > > controller? > > > > If I understand you correctly, you are trying to take tests for views > > that were previously rails functional tests and turn them into rspec > > view examples. If that is the case, you should be able to do this: > > > > template.stub!(:current_user).and_return(mock_model(User)) > > > > If not, please provide an explicit example so we can better understand > > what you''re talking about. > > > > Cheers, > > David > > > > Thanx David, > > That looks like what I was looking for. > > I will try it when I get home. > > Cheers > Daniel >Ok I''ve started to have a crack at this but it''s getting way out of hand. Everytime I stub a method there''s another one to do. I''ve also found that when there''s a partial _detail and I''ve passed the :collection => @things to it it blows up complaining that the local variable is nil in dom_id( detail ) Am I doing someting wrong? The start of my specs is before do @u = mock_model( User ) @book = mock_model( Book ) public_book = mock_model( Book ) private_book = mock_model( Book ) public_book.stub!(:title=).and_return( "Public Title" ) private_book.stub!(:title=).and_return( "Private Title" ) public_book.stub!( :title ).and_return( "Public Title" ) private_book.stub!( :title ).and_return( "Private Title" ) @u.stub!( :public_books ).and_return( [public_book] ) @u.stub!( :private_books ).and_return( [private_book] ) @clip = mock_model( Clip ) @clip.stub!( :id ).and_return( 1 ) @clips = [ @clip ] template.stub!( :current_user ).and_return( @u ) end and I''ve only started. Is it normal to have to stub this much for a view? Cheers Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070706/c135d879/attachment.html
On 7/6/07, Daniel N <has.sox at gmail.com> wrote:> On 7/6/07, Daniel N <has.sox at gmail.com> wrote: > > On 7/6/07, David Chelimsky < dchelimsky at gmail.com> wrote: > > > On 7/5/07, Daniel N <has.sox at gmail.com> wrote: > > > > Hi, > > > > > > > > I''m very new to rspec so please be patient with me. > > > > > > > > I''ve tried to take some of my tests out of the controller specs to > check for > > > > things that are rendered. > > > > > > > > This has not worked so well, since my views have the controller method > > > > > > > > current_user > > > > > > > > in quite a few places. > > > > > > > > Is there any way that I can define this so that my views will be > executed? > > > > Will this same thing occur for all helper methods that are definied in > the > > > > controller? > > > > > > If I understand you correctly, you are trying to take tests for views > > > that were previously rails functional tests and turn them into rspec > > > view examples. If that is the case, you should be able to do this: > > > > > > > template.stub!(:current_user).and_return(mock_model(User)) > > > > > > If not, please provide an explicit example so we can better understand > > > what you''re talking about. > > > > > > Cheers, > > > David > > > > > > > > Thanx David, > > > > That looks like what I was looking for. > > > > I will try it when I get home. > > > > Cheers > > Daniel > > Ok I''ve started to have a crack at this but it''s getting way out of hand. > Everytime I stub a method there''s another one to do. > > I''ve also found that when there''s a partial _detail and I''ve passed the > :collection => @things to it it blows up complaining that the local variable > is nil in > dom_id( detail )If you''re using the trunk, you can do this: template.expects_render(:partial => ''detail'', :collection => @things)> > Am I doing someting wrong? The start of my specs is > > before do > @u = mock_model( User ) > @book = mock_model( Book ) > > public_book = mock_model( Book ) > private_book = mock_model( Book ) > public_book.stub!(:title=).and_return( "Public Title" ) > private_book.stub!(:title=).and_return( "Private Title" > ) > public_book.stub!( :title ).and_return( "Public Title" ) > private_book.stub!( :title ).and_return( "Private Title" )Why are you stubbing the same calls twice each?> > @u.stub!( :public_books ).and_return( [public_book] ) > @u.stub!( :private_books ).and_return( [private_book] ) > @clip = mock_model( Clip ) > @clip.stub!( :id ).and_return( 1 ) > @clips = [ @clip ] > > template.stub!( :current_user ).and_return( @u ) > end > > and I''ve only started. Is it normal to have to stub this much for a view?Depends on how much stuff is in your view :) You''ve got a couple of options. You could create instances of the model instead. As long as you''re not saving and retrieving them there''s very little db interaction - just enough for AR to discover the attributes. If you prefer to keep it all mocked/stubbed, you could clean up a bit like this: before do @u = mock_model( User ) @book = mock_model( Book ) public_book = mock_model(Book, :title => ''Public Title'') private_book = mock_model( Book, :title => ''Private Title'') @u.stub!( :public_books ).and_return( [public_book] ) @u.stub!( :private_books ).and_return( [private_book] ) @clips = [ @clip = mock_model( Clip, :id => 1 ) ] template.stub!( :current_user ).and_return( @u ) end That stubs the same amount of stuff, but its a little cleaner. You could also write a shared behaviour that stubs current user: describe "authenticated page view", :shared => true do before(:each) do template.stub!( :current_user ).and_return( @u ) end end describe "/some/page" it_should_behave_like "authenticated page view" before(:each) do @u = mock_model( User ) @book = mock_model( Book ) public_book = mock_model(Book, :title => ''Public Title'') private_book = mock_model( Book, :title => ''Private Title'') @u.stub!( :public_books ).and_return( [public_book] ) @u.stub!( :private_books ).and_return( [private_book] ) @clips = [ @clip = mock_model( Clip, :id => 1 ) ] end end There''s probably a bit more to clean up but I''d have to see the view code. Would you mind letting us see it?> > Cheers > Daniel > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 7/6/07, David Chelimsky <dchelimsky at gmail.com> wrote:> > On 7/6/07, Daniel N <has.sox at gmail.com> wrote: > > On 7/6/07, Daniel N <has.sox at gmail.com> wrote: > > > On 7/6/07, David Chelimsky < dchelimsky at gmail.com> wrote: > > > > On 7/5/07, Daniel N <has.sox at gmail.com> wrote: > > > > > Hi, > > > > > > > > > > I''m very new to rspec so please be patient with me. > > > > > > > > > > I''ve tried to take some of my tests out of the controller specs to > > check for > > > > > things that are rendered. > > > > > > > > > > This has not worked so well, since my views have the controller > method > > > > > > > > > > current_user > > > > > > > > > > in quite a few places. > > > > > > > > > > Is there any way that I can define this so that my views will be > > executed? > > > > > Will this same thing occur for all helper methods that are > definied in > > the > > > > > controller? > > > > > > > > If I understand you correctly, you are trying to take tests for > views > > > > that were previously rails functional tests and turn them into rspec > > > > view examples. If that is the case, you should be able to do this: > > > > > > > > > > template.stub!(:current_user).and_return(mock_model(User)) > > > > > > > > If not, please provide an explicit example so we can better > understand > > > > what you''re talking about. > > > > > > > > Cheers, > > > > David > > > > > > > > > > > > Thanx David, > > > > > > That looks like what I was looking for. > > > > > > I will try it when I get home. > > > > > > Cheers > > > Daniel > > > > Ok I''ve started to have a crack at this but it''s getting way out of > hand. > > Everytime I stub a method there''s another one to do. > > > > I''ve also found that when there''s a partial _detail and I''ve passed the > > :collection => @things to it it blows up complaining that the local > variable > > is nil in > > dom_id( detail ) > > If you''re using the trunk, you can do this: > > template.expects_render(:partial => ''detail'', :collection => @things) > > > > > Am I doing someting wrong? The start of my specs is > > > > before do > > @u = mock_model( User ) > > @book = mock_model( Book ) > > > > public_book = mock_model( Book ) > > private_book = mock_model( Book ) > > public_book.stub!(:title=).and_return( "Public Title" ) > > private_book.stub!(:title=).and_return( "Private Title" > > ) > > public_book.stub!( :title ).and_return( "Public Title" ) > > private_book.stub!( :title ).and_return( "Private Title" ) > > Why are you stubbing the same calls twice each? > > > > > @u.stub!( :public_books ).and_return( [public_book] ) > > @u.stub!( :private_books ).and_return( [private_book] ) > > @clip = mock_model( Clip ) > > @clip.stub!( :id ).and_return( 1 ) > > @clips = [ @clip ] > > > > template.stub!( :current_user ).and_return( @u ) > > end > > > > and I''ve only started. Is it normal to have to stub this much for a > view? > > Depends on how much stuff is in your view :) > > You''ve got a couple of options. You could create instances of the > model instead. As long as you''re not saving and retrieving them > there''s very little db interaction - just enough for AR to discover > the attributes. > > If you prefer to keep it all mocked/stubbed, you could clean up a bit like > this: > > before do > @u = mock_model( User ) > @book = mock_model( Book ) > > public_book = mock_model(Book, :title => ''Public Title'') > private_book = mock_model( Book, :title => ''Private Title'') > > @u.stub!( :public_books ).and_return( [public_book] ) > @u.stub!( :private_books ).and_return( [private_book] ) > > @clips = [ @clip = mock_model( Clip, :id => 1 ) ] > > template.stub!( :current_user ).and_return( @u ) > end > > That stubs the same amount of stuff, but its a little cleaner. You > could also write a shared behaviour that stubs current user: > > describe "authenticated page view", :shared => true do > before(:each) do > template.stub!( :current_user ).and_return( @u ) > end > end > > describe "/some/page" > it_should_behave_like "authenticated page view" > > before(:each) do > @u = mock_model( User ) > @book = mock_model( Book ) > > public_book = mock_model(Book, :title => ''Public Title'') > private_book = mock_model( Book, :title => ''Private Title'') > > @u.stub!( :public_books ).and_return( [public_book] ) > @u.stub!( :private_books ).and_return( [private_book] ) > > @clips = [ @clip = mock_model( Clip, :id => 1 ) ] > > end > end > > There''s probably a bit more to clean up but I''d have to see the view > code. Would you mind letting us see it? > > > > > Cheers > > Danielindex.html.erb <% content_for :action_bar do %> <% @public_books = current_user.public_books %> <% @private_books = current_user.private_books %> <%= render :file => ''books/_book_list.html.erb'' -%> <% end %> <% if @book %> <div class=''book_clip_list'' id=''<%= dom_id( @book )-%>''> <h2 class=''book_header''><%= @book.title -%></h2> <ul id="book_clip_menu"> <li> <button class=''collapse_all''>Collapse All</button> <button class=''expand_all''>Expand All</button> </li> </ul> <%= render :partial => ''detail'', :collection => @clips %> </div> <% else %> <%= render :partial => ''detail'', :collection => @clips -%> <% end %> detail.html.erb <div id=''<%= dom_id( detail ) -%>'' class=''clip_container''> <div class=''clip_header''> <button class=''minimize''>-</button> <h3 id=''<%= "#{dom_id( detail )}_header" -%>''><%= detail.title-%></h3> <div> <a href=''<%= detail.url -%>'' target=''_blank''><%= URI.parse( detail.url).host -%></a><br/> <%= detail.created_at.to_s( :long ) -%> </div> </div> <div class=''content_container'' id=''<%= "#{dom_id( detail )}_content_container" -%>''> <div class=''clip_menu''> <ul class=''action_menu''> <%= render :partial => ''action_menu_links'', :locals => { :clip => detail, :book => @book } -%> </ul> <ul class=''view_menu''> <%= render :partial => ''alternative_content_links'', :locals => { :clip => detail } -%> </ul> </div> <blockquote id=''<%= "#{dom_id( detail )}_blockquote"-%>''> <% render_as = @view_type || ''html'' %> <% render_as = ''html'' unless Clip.available_types.include?( render_as ) %> <% case render_as %> <% when ''quote'' %> <%= render :partial => ''text'', :locals => { :clip => detail } %> <% when ''images'' %> <%= render :partial => ''images'', :locals => { :clip => detail } %> <% when ''html'' %> <%= render :partial => ''html'', :locals => { :clip => detail } %> <% end %> </blockquote> </div> </div> The _text, _images, _html partials are very simple so I won''t show them here. This will be enough I think to evaluate it. Thankyou for helping with this. Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070707/7a172439/attachment.html
On 7/6/07, Daniel N <has.sox at gmail.com> wrote:> > > > On 7/6/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > On 7/6/07, Daniel N <has.sox at gmail.com> wrote: > > > On 7/6/07, Daniel N <has.sox at gmail.com> wrote: > > > > On 7/6/07, David Chelimsky < dchelimsky at gmail.com> wrote: > > > > > On 7/5/07, Daniel N <has.sox at gmail.com> wrote: > > > > > > Hi, > > > > > > > > > > > > I''m very new to rspec so please be patient with me. > > > > > > > > > > > > I''ve tried to take some of my tests out of the controller specs to > > > check for > > > > > > things that are rendered. > > > > > > > > > > > > This has not worked so well, since my views have the controller > method > > > > > > > > > > > > current_user > > > > > > > > > > > > in quite a few places. > > > > > > > > > > > > Is there any way that I can define this so that my views will be > > > executed? > > > > > > Will this same thing occur for all helper methods that are > definied in > > > the > > > > > > controller? > > > > > > > > > > If I understand you correctly, you are trying to take tests for > views > > > > > that were previously rails functional tests and turn them into rspec > > > > > view examples. If that is the case, you should be able to do this: > > > > > > > > > > > > > > template.stub!(:current_user).and_return(mock_model(User)) > > > > > > > > > > If not, please provide an explicit example so we can better > understand > > > > > what you''re talking about. > > > > > > > > > > Cheers, > > > > > David > > > > > > > > > > > > > > > > Thanx David, > > > > > > > > That looks like what I was looking for. > > > > > > > > I will try it when I get home. > > > > > > > > Cheers > > > > Daniel > > > > > > Ok I''ve started to have a crack at this but it''s getting way out of > hand. > > > Everytime I stub a method there''s another one to do. > > > > > > I''ve also found that when there''s a partial _detail and I''ve passed the > > > :collection => @things to it it blows up complaining that the local > variable > > > is nil in > > > dom_id( detail ) > > > > If you''re using the trunk, you can do this: > > > > template.expects_render(:partial => ''detail'', :collection => @things) > > > > > > > > Am I doing someting wrong? The start of my specs is > > > > > > before do > > > @u = mock_model( User ) > > > @book = mock_model( Book ) > > > > > > public_book = mock_model( Book ) > > > private_book = mock_model( Book ) > > > public_book.stub!(:title=).and_return( "Public > Title" ) > > > private_book.stub!(:title=).and_return( "Private > Title" > > > ) > > > public_book.stub!( :title ).and_return( "Public Title" ) > > > private_book.stub!( :title ).and_return( "Private Title" ) > > > > Why are you stubbing the same calls twice each? > > > > > > > > @u.stub!( :public_books ).and_return( [public_book] ) > > > @u.stub!( :private_books ).and_return( [private_book] ) > > > @clip = mock_model( Clip ) > > > @clip.stub!( :id ).and_return( 1 ) > > > @clips = [ @clip ] > > > > > > template.stub!( :current_user ).and_return( @u ) > > > end > > > > > > and I''ve only started. Is it normal to have to stub this much for a > view? > > > > Depends on how much stuff is in your view :) > > > > You''ve got a couple of options. You could create instances of the > > model instead. As long as you''re not saving and retrieving them > > there''s very little db interaction - just enough for AR to discover > > the attributes. > > > > If you prefer to keep it all mocked/stubbed, you could clean up a bit like > this: > > > > before do > > @u = mock_model( User ) > > @book = mock_model( Book ) > > > > public_book = mock_model(Book, :title => ''Public Title'') > > private_book = mock_model( Book, :title => ''Private Title'') > > > > @u.stub!( :public_books ).and_return( [public_book] ) > > @u.stub!( :private_books ).and_return( [private_book] ) > > > > @clips = [ @clip = mock_model( Clip, :id => 1 ) ] > > > > template.stub!( :current_user ).and_return( @u ) > > end > > > > That stubs the same amount of stuff, but its a little cleaner. You > > could also write a shared behaviour that stubs current user: > > > > describe "authenticated page view", :shared => true do > > before(:each) do > > template.stub!( :current_user ).and_return( @u ) > > end > > end > > > > describe "/some/page" > > it_should_behave_like "authenticated page view" > > > > before(:each) do > > @u = mock_model( User ) > > @book = mock_model( Book ) > > > > public_book = mock_model(Book, :title => ''Public Title'') > > private_book = mock_model( Book, :title => ''Private Title'') > > > > @u.stub!( :public_books ).and_return( [public_book] ) > > @u.stub!( :private_books ).and_return( [private_book] ) > > > > @clips = [ @clip = mock_model( Clip, :id => 1 ) ] > > > > end > > end > > > > There''s probably a bit more to clean up but I''d have to see the view > > code. Would you mind letting us see it? > > > > > > > > Cheers > > > Daniel > > > index.html.erb > > <% content_for :action_bar do %> > <% @public_books = current_user.public_books %> > <% @private_books = current_user.private_books %> > <%= render :file => ''books/_book_list.html.erb'' -%> > <% end %> > > <% if @book %> > <div class=''book_clip_list'' id=''<%= dom_id( @book )-%>''> > <h2 class=''book_header''><%= @book.title -%></h2> > <ul id="book_clip_menu"> > <li> > <button class=''collapse_all''>Collapse All</button> > <button class=''expand_all''>Expand All</button> > </li> > </ul> > <%= render :partial => ''detail'', :collection => @clips %> > </div> > <% else %> > <%= render :partial => ''detail'', :collection => @clips -%> > > <% end %> > > > detail.html.erb > <div id=''<%= dom_id( detail ) -%>'' class=''clip_container''> > <div class=''clip_header''> > <button class=''minimize''>-</button> > <h3 id=''<%= "#{dom_id( detail )}_header" -%>''><%= detail.title > -%></h3> > <div> > <a href=''<%= detail.url -%>'' target=''_blank''><%> URI.parse(detail.url).host -%></a><br/> > <%= detail.created_at.to_s ( :long ) -%> > </div> > </div> > <div class=''content_container'' id=''<%= "#{dom_id( detail > )}_content_container" -%>''> > <div class=''clip_menu''> > <ul class=''action_menu''> > <%= render :partial => ''action_menu_links'', :locals => { :clip > => detail, :book => @book } -%> > </ul> > <ul class=''view_menu''> > <%= render :partial => ''alternative_content_links'', :locals => { > :clip => detail } -%> > </ul> > </div> > <blockquote id=''<%= "#{dom_id( detail )}_blockquote"-%>''> > <% render_as = @view_type || ''html'' %> > <% render_as = ''html'' unless Clip.available_types.include?( render_as ) > %> > <% case render_as %> > <% when ''quote'' %> > <%= render :partial => ''text'', :locals => { :clip => detail > } %> > <% when ''images'' %> > <%= render :partial => ''images'', :locals => { :clip => detail > } %> > <% when ''html'' %> > <%= render :partial => ''html'', :locals => { :clip => > detail } %> > <% end %> > > </blockquote> > </div> > </div> > > > The _text, _images, _html partials are very simple so I won''t show them > here. This will be enough I think to evaluate it. > > Thank you for helping with this.OK - there''s quite a bit going on here, and I don''t really have time to address every detail right now - but here''s a couple of things to think about: Conventional wisdom suggests that you should favor decision making in controllers and helpers rather than in the views themselves. One reason for this is that view templates boil down to a single method, so you have to provide all of the state they need every time. If your view has nothing but instance variables that get assigned from the controller, and never reach into them for their data, then you have nothing to set up in a test. Consider this: <% content_for :action_bar do %> <% @public_books = current_user.public_books %> <% @private_books = current_user.private_books %> <%= render :file => ''books/_book_list.html.erb'' -%> <% end %> That design choice requires that you set up a current_user which can provide public_books and private_books. If, instead, you handled that in the controller, you''d still have to provide a current_user for the controller examples, but it becomes much easier to start pushing things around to different methods that can each be tested in isolation, so the setup for each can get smaller. If you did this, the view example might look like this: template.expects_render(:file => ''books/_book_list.html.erb'') instead of this: template.stub!(:current_user).and_return( mock_model(User, :public_books => [], :private_books => [], ) ) template.expects_render(:file => ''books/_book_list.html.erb'') Given what you''ve got, I think you could do this (with trunk) in before(:each): ===========================controller.stub!(:dom_id).and_return("anything") template.stub!(:current_user).and_return( mock_model(User, :public_books => [], :private_books => [], ) ) template.stubs_render(:file => ''books/_book_list.html.erb'') template.stubs_render(:partial => ''detail'', :collection => @clips) assigns[:clips] => [] assigns[:book] => mock_model(Book) =========================== Then you could use Message Expectations (mocks) in each example for the specific thing you want to describe. Hope this helps. David> > Daniel > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >