[rspec-users] Test::Unit Functional failure puzzle

Zach Dennis zach.dennis at gmail.com
Sun Nov 23 13:47:49 EST 2008


On Fri, Nov 21, 2008 at 9:44 AM, James Byrne <lists at ruby-forum.com> wrote:
> David Chelimsky wrote:
>
>>
>> Without seeing the controller code, I'd guess that the controller uses
>> create, and not create! and that a validation failure is not getting
>> reported anywhere.
>>
>> If so, try changing create to create! and you should get your error.
>>
>
> Thank you. You were close enough to the actual situation that I could
> easily see what had to be done.
>
> The main problem (other than my abysmal ignorance) is that I am
> retro-fitting test to code that I wrote some time ago.  In this case
> client is a role associated to an entity.  The clients_controller
> handles the case where the entity and the client are created together in
> one pass.  I was creating a new client but not a new entity in my test
> case and so the save was failing because the entity validations were
> failing.  Changing the .save to .save! displayed the actual error in the
> test and made the entire situation clear to me.
>
> My next question is: why would one choose .save/.create over
> .save!/.create! since the former does not render the error when testing?

It's very common that whoever was filling out a form will want to be
notified of any validation
errors that may exist from their data entry. If you use #save you can
simply check to
see if it returned true or false, and then render the appropriate template. e.g:

  def create
      @user = User.new params[:user]
      if @user.save
         # yay success
      else
         render :action => "new"
      end
   end

If you use #save! then your controller action has to rescue the
exception in order to render the right page. Based on where/how you
assign the instance variables you may need to introduce a inner
begin/rescue block which makes the action more clunky and less
aesthetically appealing.

  def create
      @user = User.new params[:user]
      @user.save!
  rescue ActiveRecord::RecordInvalid
      render :action => "new"
  end

If you use .create! then your controller action doesn't have access to
an instance variable which may be needed to render the appropriate
template.

  def create
      @user = User.create! params[:user]
  rescue ActiveRecord::RecordInvalid

 render :action => "new"
  end



-- 
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com


More information about the rspec-users mailing list