[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