[rspec-users] Controller Isolation

Chris Anderson jchris at mfdz.com
Wed Nov 22 14:56:05 EST 2006


As far as your controller action goes, you might try switching from
the exception handling way of rendering different actions to using
something like:

def create
    @star = Star.new(params[:star])
    if @star.save
      redirect_to star_path(@star)
    else
      render :action => 'new'
end

This keeps your @star object available even when it is invalid, which
gives you the ability to use "error_messages_for 'star'" in your
new.rhtml. It should also make specing easier. I basically cribbed it
from scaffold_resource, so it's also the core-team blessed way.

I used to use the exception handling method, but because @star.save
returns false on failure, there's no reason to have other checks. It
also gives you the ability to do more stuff to @star after it's been
initialized but before it has to be valid. Now I'm fully a convert to
the @star.save conditional structure.

Hope this helps.

Chris


On 11/22/06, David Chelimsky <dchelimsky at gmail.com> wrote:
> On 11/21/06, Dylan Egan <dylanegan at gmail.com> wrote:
> > Hi,
> >
> > I have a project that I had running under rspec 0.6.x and recently upgraded
> > to 0.7.2.
> >
> > I am trying to isolate my controllers from the database as I go through and
> > change all the specs to run under 0.7.2.
> >
> > I am having a problem where I need to make the create! method return the
> > mocked object as well as raise RecordInvalid exception. Is this at all
> > possible?
>
> AFAIK, Ruby won't let you return an object and raise an error at the
> same time. You get one or the other.
>
> > I use the rescue statement in my controller methods and not @
> > object.new_record? or @object.valid? to check whether to redirect or render.
> >
> > -- controller --
> >
> >   def create
> >     @star = Star.create!(params[:star])
> >     redirect_to star_path(@star)
> >   rescue ActiveRecord::RecordInvalid
> >     render :action => 'new'
> >   end
> >
> > -- spec --
> >   @star = mock('star')
> >   Star.should_receive(:create!).with({ 'name' => nil }).and_return(@star)
>
> Hmmm. As I said above, I can't imagine that Ruby will let you do that.
> What I would do in this case is this:
>
> -- spec --
>   @star = mock('star')
>   Star.should_receive(:create!).with({ 'name' => nil
> }).and_raise(ActiveRecord::RecordInvalid)
>   Star.should_receive(:create).with({ 'name' => nil }).and_return(@star)
>
> -- controller --
>
>   def create
>     @star = Star.create!(params[:star])
>     redirect_to star_path(@star)
>   rescue ActiveRecord::RecordInvalid
>     @star = Star.create(params[:star])
>     render :action => 'new'
>   end
>
> OR
>
>   def create
>     @star = Star.create!(params[:star])
>     redirect_to star_path(@star)
>   rescue ActiveRecord::RecordInvalid
>     render :action => 'new'
>   end
>
>   def new
>     @star = Star.new
>   end
>
> > I'm new to all the mocking/stubbing business so my head spins are turning
> > into headaches. :)
>
> Hope that helps.
>
> David
>
> > Dylan.
> >
> > _______________________________________________
> > 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
>


-- 
Chris Anderson
http://jchris.mfdz.com


More information about the rspec-users mailing list