[rspec-users] DRYer controller specs

David Chelimsky dchelimsky at gmail.com
Fri Apr 27 09:57:16 EDT 2007


On 4/27/07, Chris Hoffman <bosshoff at gmail.com> wrote:
> Your's is a good question.  I too have been looking for ways to DRY up
> my controller tests.  The more I am starting to obey a CRUD-only
> design, the more duplication I am encountering in these specs.  Right
> now, I am combating this dilemma by making a bunch of methods in
> spec_helper that define _context_ and _specify_ statements, such as:
>
> def specify_should_handle_an_invalid_id_nicely(params)
>   controller = "#{params[:controller].camelize}Controller"
>   model = params[:controller].classify.constantize
>   params[:redirect_to] ||= { :action => 'index' }
>   params[:actions] ||= [:edit, :update, :show, :destroy]
>
>   params[:actions].to_a.each do |action|
>     context "#{controller}##{action}, given an id" do
>       controller_name params[:controller]
>
>       specify "should call #{model}.find_by_id, instead of #{model}.find" do
>         model.should_receive(:find_by_id).with("the id")
>         send(:process, action, :id => "the id")
>       end
>     end
>
>     context "#{controller}##{action}, not given a valid id" do
>       controller_name params[:controller]
>
>       setup do
>         model.stub!(:find_by_id)
>       end
>
>       specify "should redirect_to #{params[:redirect_to]}" do
>         send(:process, action)
>         response.should_redirect_to params[:redirect_to]
>       end
>
>       specify "should populate the flash with a message indicating
> that the record wasn't found" do
>         send(:process, action)
>         flash[:notice].should == "#{model} not found"
>       end
>     end
>   end
> end
>
> This approach is obviously clunky, and I would myself like a better
> way to specify controller-wide contracts, as it were.  Just as above,
> any action that requires an id as a parameter should behave a certain
> way, and I shouldn't have to define this behavior in each controller's
> specification; it should be application-wide.

Would http://rubyforge.org/tracker/?func=detail&group_id=797&aid=9605&atid=3151
satisfy your needs?


More information about the rspec-users mailing list