Hello, I''m having a hard time testing my controllers that use respond_to. I''m trying to test that I can correctly handle each MIME type on request. For instance, I have this: respond_to do |format| format.html format.json end And I''ve tried things like this: get ''show'', :id => databases(:one).id, :format => ''json'' response.should render_template(''show'') but I keep getting a nil template. I know this works in the code, when I try a URI like http://localhost:3000/foo.json Any tips for setting the format or MIME Type correctly so I can activate other respond_to blocks? Thanks very much, Seth
Hm, of course, now that I have sent the previous email, I found the bug in my code and have fixed it. So I know I am using RSpec correctly with controllers and a respond_to block. Using the :format => ''json'' attribute in my get call was all I needed. However, not matter what the format I choose, the template rendered is always "databases/show" (this is essentially correct behavior). However, it''s hard to determine which show was rendered: show.json.erb or show.html.erb I can check the content-type header, but that''s not exactly what I''d like to test. Is there a better way to write a spec to ensure that the correct template is rendered when I use certain formats? Seth On Mon, Mar 24, 2008 at 8:35 PM, Seth Ladd <sethladd at gmail.com> wrote:> Hello, > > I''m having a hard time testing my controllers that use respond_to. > I''m trying to test that I can correctly handle each MIME type on > request. > > For instance, I have this: > > respond_to do |format| > format.html > format.json > end > > And I''ve tried things like this: > > get ''show'', :id => databases(:one).id, :format => ''json'' > response.should render_template(''show'') > > but I keep getting a nil template. > > I know this works in the code, when I try a URI like > http://localhost:3000/foo.json > > Any tips for setting the format or MIME Type correctly so I can > activate other respond_to blocks? > > Thanks very much, > Seth >
On Tue, Mar 25, 2008 at 2:06 AM, Seth Ladd <sethladd at gmail.com> wrote:> Hm, of course, now that I have sent the previous email, I found the > bug in my code and have fixed it. So I know I am using RSpec > correctly with controllers and a respond_to block. Using the :format > => ''json'' attribute in my get call was all I needed. > > However, not matter what the format I choose, the template rendered is > always "databases/show" (this is essentially correct behavior). > However, it''s hard to determine which show was rendered: > show.json.erb or show.html.erbThere is a guideline in TDD that you should test your code and not other people''s code. The behaviour you''re interested in testing is that of ActionController::Base, not of your code.> I can check the content-type header, but that''s not exactly what I''d > like to test. > > Is there a better way to write a spec to ensure that the correct > template is rendered when I use certain formats?The transformation from loosely-bound name (''databases/show'') to explicit template name with extensions happens deep in ActionController::Base. Between that fact and the aforementioned guideline, there is no direct support for what you are looking for in rspec_on_rails. You *can* do this to get closer to what you are looking for: controller.expect_render(hash_including(:xml => anything)) or controller.expect_render(hash_including(:json => anything)) But I, personally, would not. Since this is not supported directly by rspec_on_rails, should the Rails implementation of render change you''d be on your own to keep up with those changes. HTH, David> > Seth > > > > On Mon, Mar 24, 2008 at 8:35 PM, Seth Ladd <sethladd at gmail.com> wrote: > > Hello, > > > > I''m having a hard time testing my controllers that use respond_to. > > I''m trying to test that I can correctly handle each MIME type on > > request. > > > > For instance, I have this: > > > > respond_to do |format| > > format.html > > format.json > > end > > > > And I''ve tried things like this: > > > > get ''show'', :id => databases(:one).id, :format => ''json'' > > response.should render_template(''show'') > > > > but I keep getting a nil template. > > > > I know this works in the code, when I try a URI like > > http://localhost:3000/foo.json > > > > Any tips for setting the format or MIME Type correctly so I can > > activate other respond_to blocks? > > > > Thanks very much, > > Seth > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
> There is a guideline in TDD that you should test your code and not > other people''s code. The behaviour you''re interested in testing is > that of ActionController::Base, not of your code.I, of course, do not want to test Rails. I do, however, want to ensure that I have a block to handle the correct MIME type and I have a template for that MIME type. I suppose checking for the template "foo/show" is good enough in this case. If there was an error, I''d get a nil there. I guess where this strategy falls down is if I forgot to put a responds_to in my controller. Then, no matter the format, I''ll still render ''foo/show'' (assuming I do indeed have that template) Thanks for your help, Seth
On Tue, Mar 25, 2008 at 11:38 AM, Seth Ladd <sethladd at gmail.com> wrote:> > There is a guideline in TDD that you should test your code and not > > other people''s code. The behaviour you''re interested in testing is > > that of ActionController::Base, not of your code. > > I, of course, do not want to test Rails. I do, however, want to > ensure that I have a block to handle the correct MIME type and I have > a template for that MIME type. I suppose checking for the template > "foo/show" is good enough in this case. If there was an error, I''d > get a nil there.If you''re really concerned about it, you could also mock respond_to: format = mock("format") format.should_receive(:json).and_return("this text") controller.should_receive(:respond_to).and_yield(format) get ''path/to/file'', :format => ''json'' That seems a bit implementation heavy, but it might give you the feeling of confidence you''re looking for. HTH, David> > I guess where this strategy falls down is if I forgot to put a > responds_to in my controller. Then, no matter the format, I''ll still > render ''foo/show'' (assuming I do indeed have that template) > > Thanks for your help, > > > Seth > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Hi Seth, To get around this, are you able to test the response.headers collection? This tests the code that you wrote, rather than the template logic performed by rails. response.headers[''Content-Type''].should == "text/html" Untested, of course... but it may work :) -- Matt Berther http://www.mattberther.com On Mar 25, 2008, at 10:38 AM, Seth Ladd wrote:>> There is a guideline in TDD that you should test your code and not >> other people''s code. The behaviour you''re interested in testing is >> that of ActionController::Base, not of your code. > > I, of course, do not want to test Rails. I do, however, want to > ensure that I have a block to handle the correct MIME type and I have > a template for that MIME type. I suppose checking for the template > "foo/show" is good enough in this case. If there was an error, I''d > get a nil there. > > I guess where this strategy falls down is if I forgot to put a > responds_to in my controller. Then, no matter the format, I''ll still > render ''foo/show'' (assuming I do indeed have that template) > > Thanks for your help, > Seth > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
To do this, I''ve typically just add the HTTP_ACCEPT header. I can''t remember where I picked this up, but it''s does specify a format in your respond_to block: Here''s the do_request (and a sample spec) for one of my specs where I''m checking for a generated csv file: def do_request @request.env["HTTP_ACCEPT"] = "text/csv" get :show, :id => "1" end it "should return a csv download" do @controller.should_receive(:send_file).with(@file, {:filename => "report-#{@report.id }.csv", :type => ''text/csv'', :disposition => ''attachment''}) do_get end Now my assumption is that your mime-type would need to be registered in rails for this to work (if you have need of one outside of the norm), which arguably has the added benefit of ensuring you added it into your environment initializers... -- Tim Glen On 25-Mar-08, at 12:46 PM, Matt Berther wrote:> Hi Seth, > > To get around this, are you able to test the response.headers > collection? This tests the code that you wrote, rather than the > template logic performed by rails. > > response.headers[''Content-Type''].should == "text/html" > > Untested, of course... but it may work :) > > -- > Matt Berther > http://www.mattberther.com > > > > > On Mar 25, 2008, at 10:38 AM, Seth Ladd wrote: > >>> There is a guideline in TDD that you should test your code and not >>> other people''s code. The behaviour you''re interested in testing is >>> that of ActionController::Base, not of your code. >> >> I, of course, do not want to test Rails. I do, however, want to >> ensure that I have a block to handle the correct MIME type and I have >> a template for that MIME type. I suppose checking for the template >> "foo/show" is good enough in this case. If there was an error, I''d >> get a nil there. >> >> I guess where this strategy falls down is if I forgot to put a >> responds_to in my controller. Then, no matter the format, I''ll still >> render ''foo/show'' (assuming I do indeed have that template) >> >> Thanks for your help, >> Seth >> _______________________________________________ >> 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