[rspec-users] Comments wanted about spec'ing out a couple controller methods

aslak hellesoy aslak.hellesoy at gmail.com
Wed May 23 04:29:31 EDT 2007


On 5/22/07, Joe Van Dyk <joevandyk at gmail.com> wrote:
> On 5/22/07, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:
> > On 5/22/07, Joe Van Dyk <joevandyk at gmail.com> wrote:
> > > (oops, accidentally sent this to the rspec-devel list, sorry about that)
> > >
> > > Could someone help me spec out these Rails controller methods?  I
> > > don't know where to get started, especially with the transaction
> > > stuff.  Or, if anyone else could suggest ways I could improve the
> > > code, that would be great as well.
> > >
> >
> > This is a very busy controller. I recommend you move as much logic as
> > possible down to the model. Along the lines of
> > http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model
> >
> > I am almost 100% sure that you wrote this controller before you wrote
> > the spec - or that you don't have a spec. And that's how your
> > controller got so fat ;-)
> >
> > I really recommend writing the spec first - starting with an empty
> > controller (or freshly generated one). Then let the failing tests
> > guide you in what you have to do in the controller - not the other way
> > around.
> >
> > Aslak
>
> That's obvious.  :-)  I just started with rspec after the railsconf.
> There's normal rails tests for these methods, but I'm trying to move
> towards more mocks.
>
> So, in this example, maybe I'd want to do something like this?
>
> def create
>     @puzzle = Puzzle.new
>     @puzzle.populate_and_save_with_user_and_puzzle_and_media_attributes
> @user, params[:puzzle], params[:media]
>     if @puzzle.new_record
>        # error stuff
>     else
>        # success stuff
>     end
> end
>
> And then in Puzzle#populate_and_save_with_user_and_puzzle_and_media_attributes
> (once i find a better name) would have the transaction stuff in there?
>

Yes, that looks much, much better. More decoupled, more testable. When
writing your specs for the controller you can now just mock the calls
to #populate_and_save_with_user_and_puzzle_and_media_attributes and
#new_record? so you can focus on how the controller behaves.

Then I'd still recommend that the model specs go against a real
database. Here you can use fixtures, or you can do like me - create
all the associated objects in the example for more clarity.

Cheers,
Aslak

> > > Puzzle has_one Media.  Both are AR model objects.
> > >
> > > class PuzzlesController < ApplicationController
> > >
> > >  # a before_filter fills in @user
> > >
> > >  def create
> > >    @puzzle = Puzzle.new(params[:puzzle])
> > >    @puzzle.user = @user
> > >
> > >    @media = Media.new(:uploaded_data => params[:media])
> > >
> > >    Puzzle.transaction do
> > >      @puzzle.media = @media
> > >      @puzzle.save! &&  @media.save!
> > >      flash[:notice] = "Success!"
> > >      redirect_to puzzle_path(@puzzle)
> > >    end
> > >  rescue ActiveRecord::RecordInvalid => e
> > >    @media.valid? # force checking of errors even if @puzzle.save!
> > > failed
> > >    flash[:error] = "Problem submitting the One Word Wonder..."
> > >    render :partial => 'new', :layout => true
> > >  end
> > >
> > >  def update
> > >    @puzzle = Puzzle.find params[:id]
> > >    Puzzle.transaction do
> > >      @puzzle.attributes = params[:puzzle]
> > >      if params[:media] and params[:media].size > 0
> > >        @puzzle.media = Media.new :uploaded_data => params[:media]
> > >      end
> > >      @puzzle.save!  &&   @puzzle.media.save!
> > >    end
> > >  rescue ActiveRecord::RecordInvalid => e
> > >    @media.valid?
> > >    flash[:error] = "Problem updating the One Word Wonder..."
> > >    render :action => 'edit'
> > >  end
> > >
> > > Thanks,
> > > Joe Van Dyk
> > > _______________________________________________
> > > 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
>


More information about the rspec-users mailing list