1

Below is my apex class:

public void submitForApproval(List<Account> acc)
{

    try{

        for(SObject ac :acc) {

            if((ac.Account_Record_Type_Name__c == 'A' || ac.Account_Record_Type_Name__c == 'B') &&  ac.Status__c == 'New'){
                // Create an approval request for the Account
                Approval.ProcessSubmitRequest submitRequest = new Approval.ProcessSubmitRequest();
                submitRequest.setComments('Submitting request for approval');
                submitRequest.setObjectId(ac.id);
                submitRequest.setSubmitterId(ac.CreatedById); 
                submitRequest.setProcessDefinitionNameOrId('Account for Approval');           
                Approval.ProcessResult result = Approval.process(submitRequest);    
                system.debug('Result ' + result.isSuccess() + 'NewObj ID' + ac.Id);
            }
        }

    }catch(Exception ex){
        system.debug('Exception in Approval Process submision and error is--->'+ex);

        Batch.trackErrorLog(CLASS_NAME, 'submitForApproval',
                                    'Exception Line Number:' + ex.getLineNo() +
                                    'Exception Type' + ex.getType()+                                                             
                                    'Exception Message' + ex.getmessage());
    }

}

I tried to write a test class like this:

Account testdelAcc=new Account(Name = 'Test DelAcc');

try{
    testdelAcc.RecordTypeId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('ABC').getRecordTypeId();
    insert testdelAcc;
}
catch(Exception e)
{
    system.assertEquals(e.getMessage(), e.getMessage());
}

I am trying to pass Invalid Record Type but it does not cover the catch block. Can someone help me what I am missing here?

1

The way you have written test method logic, it will never enter in catch block as in your main class you are not throwing an exception when recordtype is Invalid.

submitForApproval method will throw the exception if system is unable to process the submit for approval.

You can change your code as below if possible.

Approach 1

Pass processDefinitionNameOrId as an argument to this method

public void submitForApproval(List<Account> acc, String processDefinitionNameOrId)
{

    try{

        for(SObject ac :acc) {

            if((ac.Account_Record_Type_Name__c == 'A' || ac.Account_Record_Type_Name__c == 'B') &&  ac.Status__c == 'New'){
                // Create an approval request for the Account
                Approval.ProcessSubmitRequest submitRequest = new Approval.ProcessSubmitRequest();
                submitRequest.setComments('Submitting request for approval');
                submitRequest.setObjectId(ac.id);
                submitRequest.setSubmitterId(ac.CreatedById); 
                submitRequest.setProcessDefinitionNameOrId(processDefinitionNameOrId);           
                Approval.ProcessResult result = Approval.process(submitRequest);    
                system.debug('Result ' + result.isSuccess() + 'NewObj ID' + ac.Id);
            }
        }

    }catch(Exception ex){
        system.debug('Exception in Approval Process submision and error is--->'+ex);

        PSABatchUtil.trackErrorLogs(CLASS_NAME, 'submitForApproval',
                                    'Exception Line Number:' + ex.getLineNo() +
                                    'Exception Type' + ex.getType()+                                                             
                                    'Exception Message' + ex.getmessage());
    }
}

Test Class

From the test method, pass invalid process definition Id for which System will throw the exception.

One more point, your assert statement. What you are trying to compare with the assertEquals() when you are putting both expected output in both the arguments.

Follow best practices writing test class.

Account testdelAcc=new Account(Name = 'Test DelAcc');

YourClass cls = new YourClass();

    insert testdelAcc;
    List<Account> lstAccount = new List<Account>();
    lstAccount.add(testdelAcc);
    cls.submitForApproval(lstAccount, 'any invalid processDefinitionNameOrId');
   //check any values create in PSABatchUtil.trackErrorLogs 

Approach 2

Without changing method signature, you could declare a variable for processDefinitionNameOrId

@TestVisible private String processDefinitionNameOrId = 'Account for Approval' ;

public void submitForApproval(List<Account> acc)
{

    try{

        for(SObject ac :acc) {

            if((ac.Account_Record_Type_Name__c == 'A' || ac.Account_Record_Type_Name__c == 'B') &&  ac.Status__c == 'New'){
                // Create an approval request for the Account
                Approval.ProcessSubmitRequest submitRequest = new Approval.ProcessSubmitRequest();
                submitRequest.setComments('Submitting request for approval');
                submitRequest.setObjectId(ac.id);
                submitRequest.setSubmitterId(ac.CreatedById); 
                submitRequest.setProcessDefinitionNameOrId(processDefinitionNameOrId);           
                Approval.ProcessResult result = Approval.process(submitRequest);    
                system.debug('Result ' + result.isSuccess() + 'NewObj ID' + ac.Id);
            }
        }

    }catch(Exception ex){
        system.debug('Exception in Approval Process submision and error is--->'+ex);

        PSABatchUtil.trackErrorLogs(CLASS_NAME, 'submitForApproval',
                                    'Exception Line Number:' + ex.getLineNo() +
                                    'Exception Type' + ex.getType()+                                                             
                                    'Exception Message' + ex.getmessage());
    }
}

Test class

Assign any invalid values from test class to processDefinitionNameOrId.

Account testdelAcc=new Account(Name = 'Test DelAcc');

YourClass cls = new YourClass();

    insert testdelAcc;
    List<Account> lstAccount = new List<Account>();
    lstAccount.add(testdelAcc);
    cls.processDefinitionNameOrId = 'any invalid processDefinitionNameOrId';
    cls.submitForApproval(lstAccount);
    //check any values create in PSABatchUtil.trackErrorLogs 
}
| improve this answer | |
  • Is it not possible to over catch block without passing additional parameter in the method? – Dhananjay Patil May 31 '17 at 15:09
  • yes, that can be possible. find updated answer – Santanu Boral May 31 '17 at 15:17
  • unfortunately it is not covering the catch part even after making changes suggested by you :( – Dhananjay Patil May 31 '17 at 15:30
  • you could check any values created in PSABatchUtil.trackErrorLogs – Santanu Boral May 31 '17 at 15:39
  • I often add a very long string for the record name - currently the limit is 80 chars - make it longer and it causes the save to fail and you enter the catch block. – Caspar Harmer May 31 '17 at 23:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.