Jump to content

The ultimate community for Ruby on Rails developers.


Photo

Problems testing a destroy failure

ruby rails testing

  • Please log in to reply
3 replies to this topic

#1 clem_c_rock

clem_c_rock

    Passenger

  • Members
  • 4 posts

Posted 05 January 2014 - 07:05 PM

Problems testing a destroy failure

 

Hello,

   I'm trying to test an active record object destroy failure but I'm having problems creating a failure situation.  I have a before_filter method called 'require_user_payment_info' which validates the @payment_info object before the delete method is called so I can't create a 'bad' @payment_info object before the delete method is called.

 

Here's the require_user_payment_info method:

 

  def require_user_payment_info 
    @payment_info = credit_card_model.slave.find_by_user_guid(user_guid)
    if !@payment_info || @payment_info.user_guid != user_guid
      redirect_to(:controller => 'store', :action => 'index') and return false
    else
      if((@payment_info.card_expires_year.to_i < Date.today.year) || 
          ((@payment_info.card_expires_month.to_i < Date.today.month) && (@payment_info.card_expires_year.to_i == Date.today.year)))        
        @payment_info.card_account_public = "" #clear this out so the user is forced to re-enter the credit card number
        @payment_info.valid?        
        flash.now[:error] = t('ui_flash_errors.card_expired_error')
      end
    end
  end

 

 

And the actual delete method:

 

  def delete
    # required to be called via a delete request
    redirect_to :action => 'edit' and return if !request.delete?
    if @payment_info.destroy
      flash[:notice] = "Delete SUCCESSFUL"
      redirect_to :action => 'new'
    else
      flash[:error] = "Delete failed"
      redirect_to :action => 'edit'
    end

 

Any ideas?

 

Thanks!



#2 stevieing

stevieing

    Dispatcher

  • Members
  • 40 posts

Posted 06 January 2014 - 01:33 PM

Hi

 

If you are having problems testing a failure then this would be considered a 'code smell' i.e. a problem with your logic.

 

Firstly why are you using the delete and not the destroy action and why do you need to test if the request is a delete?

 

Secondly what testing strategy are you using? Are you using any kind of testing framework?

 

It looks to me like the require_user_payment_info method might be in the wrong place. It may be better to move it into the model using the before_destroy callback. This would  give you more control, give you better ability to handle the errors and test failures using unit tests.

 

Hope this helps

 

Steve.



#3 clem_c_rock

clem_c_rock

    Passenger

  • Members
  • 4 posts

Posted 06 January 2014 - 03:30 PM

Thanks for getting back to me on this.

 

First of all, I should have made this more clear - the delete action is in the controller, not the model and the @payment_info model object is using the destroy method.

 

As far as 'code smell', this method seems to be as straight forward as possible - you attempt to destroy a verified active record object and if the destroy is successful, then redirect to the the new action, if it fails display the error and redirect to the edit method.   I don't see a logic problem anywhere in this method.

 

For testing strategies - I'm using the out-of-the-box ActionController::TestCase for my test suite.

 

I feel the require_user_payment_info is valid because it's a before_filter that is used for these methods:  [:show, :edit, :update, :delete]



#4 clem_c_rock

clem_c_rock

    Passenger

  • Members
  • 4 posts

Posted 08 January 2014 - 02:17 AM

Bingo - here's my solution:
 
def test_unsuccessful_delete
    payment_info = Factory.create(:payment_info, :user_guid=>@user.guid, :card_expires_month=>'04', 
                                    :card_expires_year=>(Date.today.year+2).to_s, :cardholder_city=>"test city",
                                      :cardholder_state=>'NC', :cardholder_country=>'US', :cardholder_zip=>'27612')
    PaymentInfo.any_instance.stubs(:destroy).returns(false)
    
    delete(:delete, {}, @session)
    assert_response(:redirect)
    assert_equal false, assigns(:payment_info).blank?
    assert_redirected_to({:controller=>'account', :action=>'edit'})
    assert_equal flash[:error], "There was an error deleting your credit card information. Please try again."
  end
 
Thanks for your help!





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users