+ Start a Discussion
Sherwin BetontaSherwin Betonta 

How can I cover the catch block and the increment in my test Class?

Good day. How can I cover the catch clock with my current class. I'm stuck at 96% code coverage.
public with sharing class AccOppRecalcHelperClass {
    
    //this method which will be called in the trigger
    public static void opportunityTriggerMethod(List<Opportunity> oppList, Map<Id,Opportunity> oldOpp){
        
        //instantiate a list of ID's to store id's of account records
       List<id> accId = new List<id>();
        //instantiate a list of accounts
       List<account> acc = new List<account>();
        //initialize string variable closedWon to Closed Won stage field value stored in custom label
        String Closed_Won = Label.Closed_won;
        //initialize string variable closedLost to Closed Lost stage field value stored in custom label
        String Closed_Lost = Label.Closed_lost;
        String oldaccstat;
        String acctstat;
        Integer oppClosedLost = 0;
        Integer oppClosedWon = 0;
        
        //checks opportunity records from opportunity list
       for(Opportunity opp: oppList){
          //checks if account related to opportunity field is not empty
           if(opp.AccountId != NULL){
               //adds account ID related to opportunity record to list of ID's
               accId.add(opp.AccountId); 
           }
             
       }
        for (Opportunity oppRec : [SELECT Id, Name, StageName FROM Opportunity WHERE AccountId IN :accId AND StageName != NULL]){
            if( oppRec.StageName == Closed_Won){
                oppClosedWon++;
               
            }
            else if (oppRec.StageName == Closed_Lost){
                oppClosedLost++;
            }
        }
        for (Account myAccount : [SELECT ID, Number_of_Opportunities_Won__c, Number_of_Opportunities_Lost__c FROM Account WHERE ID in :accId ]){
            
                myAccount.Number_of_Opportunities_Won__c = oppClosedWon;
                myAccount.Number_of_Opportunities_Lost__c = oppClosedLost;
                acc.add(myAccount);
            
        }
            
        if (acc.size()>0){
            try{
               update acc; 
            }
            catch(Exception e){
                System.debug(e);
            }
        }
        
    } 
}
This is my test class


 
@isTest
public class AccountOpportunityRecalculationTest {
  
private static testMethod void updateStage(){
    User sysAd = [SELECT Id,Name FROM User WHERE FirstName = 'Sherwin'];
      System.runAs(sysAd) {
         // The following code runs as System Administrator.
         Account[] accts = TestDataFactory.createAccountsWithOpps(1, 1, 'Closed Won');
         // The following code runs as user in Marketing Group.
         User MarketingUser = [SELECT Id,Name FROM User WHERE FirstName = 'Mario'];
         Test.startTest();
          try {
              System.runAs(MarketingUser) {
                    // Query for the opportunity, which has been associated with an account.
                    Opportunity opportunityToUpdate = [SELECT StageName FROM Opportunity 
                                                       WHERE StageName = 'Closed Won' ORDER BY LastModifiedDate DESC NULLS FIRST LIMIT 1];
                  // Update the billing city.
        			opportunityToUpdate.StageName = 'Closed Lost';
                  // Make the update call.
        			update opportunityToUpdate;
                  	System.assertEquals('Closed Lost', opportunityToUpdate.StageName , 'Expected opportunity with Closed Lost stage name');
              }
          
		} catch(Exception e) {
    		System.debug('An unexpected error has occurred: ' + e.getMessage());
	}         	
         }
         Test.stopTest();
        }
}
Bryan Leaman 6Bryan Leaman 6
Do you need to? 96% coverage is pretty good. Afaik, it's pretty difficult to force an update to fail when you expect it to never fail. 
Alternatively, do you really want the process to fail without any notification if there's a problem? If I don't expect a DML operation to fail, I usually do NOT code a try/catch block around it. If it fails, it will escalate the exception up the program stack until something *does* handle a failure or you get back to the user-interface and issue an error so the user can see that whatever they were trying did not succeed (and why). 
Bryan Leaman 6Bryan Leaman 6
One way you might try to force a failure on the update statement is to add a SOQL query in the test class before you update the opportunity that reads the account record with "FOR UPDATE". That should lock the record, but it will cause the test class to wait for a timeout on locking the record it's trying to update. I would not consider this a best practice. Hopefully someone else can chime in if they have a better suggestion.