[rspec-users] controller spec with model that validates_uniqueness

Daniel N has.sox at gmail.com
Thu Aug 23 21:53:56 EDT 2007


On 8/24/07, Courtenay <court3nay at gmail.com> wrote:
>
> Does this work?
>
>    Image.stub!(:validates_uniqueness_of).and_return(true)
>
>
> On 8/23/07, s.ross <cwdinfo at gmail.com> wrote:
> > I want to use mocks and stubs to test the controller, but am having
> > trouble getting my validation not to trigger. Here's the code:
> >
> > # spec:
> >
> >      Image.stub!(:find).and_return(@image)
> >      @image.should_receive(:save!).once.with(:any_args)
> >      put :update, :id => @image.id, :category_id =>
> > @category.id, :image => {:name => 'test', :image_number => 13554}
> >
> > #model
> >
> >    validates_presence_of :name
> >    validates_uniqueness_of :name, :allow_nil => true
> >
> > # rspec output
> >
> > ActiveRecord::RecordInvalid in 'ImagesController should update a
> > database record when it receives a PUT'
> > Validation failed: Name has already been taken, Image number has
> > already been taken
> >
> >
> > It seems AR is not detecting that this is an edit/update that will
> > not cause a uniqueness conflict. I believe the code in the model
> > needs to remain in place because I don't want a user creating a name
> > conflict by editing an existing name into one that already exists in
> > the database. Any thoughts on how better to spec this?
> >
> > Thanks
> > _______________________________________________


Why use a real image at all?  I usually use mock_model on these and then
stub/mock the specific calls in the controller method.  This way your not
testing the model at all.  Just the controller.  Of course, they can get
pretty complex with all the stubbing etc.

    Image.stub!(:find).and_return(@image)
    @image.should_receive(:save!).once.with(:any_args)
    put :update, :id => @image.id, :category_id =>
@category.id, :image => {:name => 'test', :image_number => 13554}

could become.

@category = mock_model( Category, :id => 1 ) # Not sure where this one is
used other than the call to put
@image = mock_model( Image, :id => 2 )
@image.should_receive( :save! ).once.with( :any_args ).and_return( true )
Image.stub!( :find ).and_return( @image )

put :update, :id => @image.id, :category_id =>
@category.id, :image => {:name => 'test', :image_number => 13554}

This way you're not reaching into the model to check your controller.

HTH
Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070824/7a761815/attachment.html 


More information about the rspec-users mailing list