+ Start a Discussion
Christi Kane gobucksChristi Kane gobucks 

How to add to this test class to cover the exception errors?

Our partner only covered 60% of the code before they were furloughed (COVID stuff). I see that the exeptions weren't covered. Below is the controller class and then the test class as it exists now. I'm stumped how to add to it to catch the exceptions.
public class wv6_TruckloadQuoteController{
    public static FINAL String QMP_GETQUOTE_ENDPOINT = 'api/csm/sls/qmb/v1/basicQuotes';
    public static FINAL Integer TIMEOUT_VAL =120000;//120000;
    public static FINAL String STR_QMB_GETQUOTE_METHOD = 'GET';
    public static FINAL String CONTENT_TYPE = 'Content-Type';
    public static FINAL String APPLICATION_JSON = 'application/json';
    public static FINAL String STR_ENVIRONMENT ='environment';
    public static FINAL String STR_ACCEPT ='Accept';
    public static FINAL String STR_AUTHORIZATION = 'Authorization';
    public static FINAL String STR_BASIC = 'BASIC';
    public static FINAL String STR_GENERATE_QUOTE_BOOLEAN = 'True';
    // method used to make callout and get the response
    public static wv6_BasicQuotesResult fetchDataOnSubmit(Quote__c quoteObj){
        String customerName = '';
        if(quoteObj != null){
            if(quoteObj.Account__c != null){
                customerName = [select name from account where id =: quoteObj.Account__c limit 1].name;
        //make callout to get data. have used 'Get Quote -- The Big Bambino' params mentioned in Quotey Mcboaty API docs.
        API_Endpoints__mdt endpointDetails = RestAPIUtils.getAPI_EndpointsFromMetadata('ESB',null);
        if(endpointDetails==null || endpointDetails.Endpoint_URL__c=='')
            throw new AuraHandledException('No API Details found from metadatatype.');
        HttpRequest request = new HttpRequest();
        string paramStr = '/?';
        paramStr += 'orig_zip=' + quoteObj.Origin_Postal_Code_Text__c  ;
        paramStr += '&'+ 'dest_zip='+ quoteObj.Destination_Postal_Code_Text__c ;
        paramStr += '&'+ 'weight='+ quoteObj.Weight__c ;
        paramStr += '&'+ 'miles='+ quoteObj.Miles__c ; // need to check the value
        //paramStr += '&'+ 'user_id='+ 3 ; // need to check the value
        //paramStr += '&'+ 'ae_id='+ 1000 ; // need to check the value
        paramStr += '&'+ 'pickup_date='+ String.valueOf(quoteObj.Pickup_Date__c);//'2019-01-06' ;
        //paramStr += '&'+ 'customer_name='+ customerName ;
        paramStr += '&'+ 'generate_quote_id='+STR_GENERATE_QUOTE_BOOLEAN;
        request.setHeader(STR_ENVIRONMENT, endpointDetails.ESB_Environment__c);
        request.setHeader(CONTENT_TYPE, APPLICATION_JSON);
        Blob headerValue = Blob.valueOf(endpointDetails.Username__c + ':' + endpointDetails.Password__c);
        String authorizationHeader = STR_BASIC+' ' + EncodingUtil.base64Encode(headerValue);
        request.setHeader(STR_AUTHORIZATION, authorizationHeader);
        request.setHeader(STR_ACCEPT, APPLICATION_JSON);
        request.setEndpoint(endpointDetails.Endpoint_URL__c + QMP_GETQUOTE_ENDPOINT + paramStr);
        Http h = new Http();
        HTTPResponse response;
            response = h.send(request);
        }catch(Exception e){
            throw new AuraHandledException('Callout Error: There was an error retrieving your quote. Please call HNRY for a quote.   '  
                                           +e.getMessage()+'  '
                                           + e.getStackTraceString());
        // Parse the JSON response
        if(response <> null){
            if (response.getStatusCode() != 200) {
                System.debug('The status code returned was not expected: ' +
                             response.getStatusCode() + ' ' + response.getStatus());
                throw new AuraHandledException('Error from Endpoint:'+response.getStatusCode()+' '
                                               + response.getStatus());
            } else{
                String strResponse = response.getBody();
                System.debug('strResponse==> ' +strResponse);
                wv6_BasicQuotesResult quoteResult = wv6_BasicQuotesResult.parse(response.getBody());
                wv6_BasicQuotesResult quoteResultFinal = quoteResult;
                    String market_codeOrigSTR = '';
                    String market_codeDestSTR = '';
                    //get market codes from A or B or C, whatever is returned for origin
                    if(quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.A <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.A <> null){
                        market_codeOrigSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.A.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.C <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.C <> null){
                        market_codeOrigSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.C.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.B <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.B <> null){
                        market_codeOrigSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.orig.B.market_code;
                    //get market code from A or B or C, whatever is returned for destination
                    if(quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.A <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.A <> null){
                        market_codeDestSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.A.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.C <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.C <> null){
                        market_codeDestSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.C.market_code;
                    }else if(quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.B <> null && quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.B <> null){
                        market_codeDestSTR = quoteResult.basicQuoteOutput.pricing_details.major_metro.dest.B.market_code;
                    // update response JSON marketCode field API names to access dynamically in lightning fo nearby_markets num_loads, num_trucks, etc
                    String strToRemove = '"'+market_codeOrigSTR+'":';
                    String strToReplace = '"'+'mrktNearByOrig'+'":';
                    String strUpdatedResponse = strResponse.replaceFirst(strToRemove,strToReplace);
                    strToRemove = '"'+market_codeDestSTR+'":';
                    strToReplace = '"'+'mrktNearByDest'+'":';
                    String finalResponse = strUpdatedResponse.replaceFirst(strToRemove,strToReplace);
                    quoteResultFinal = wv6_BasicQuotesResult.parse(finalResponse);
                }catch(Exception e){
                    throw new AuraHandledException('Error parsing nearby markets/major metros:'+ e.getMessage());
                return quoteResultFinal;
        return null;
    // method used to save Quote .
    public static Id saveQuote(Quote__c quoteObj){
            insert quoteObj;
            return quoteObj.Id;
        }catch(Exception e){
            throw new AuraHandledException('Error saving Quote Record:'+ e.getMessage());
    //Fetches the user details - profile and public group
    public static userDetails getUserDetails(){
            userDetails result = new userDetails();
            Id profileId = userinfo.getProfileId();
            result.profileName=[Select Id,Name from Profile where Id=:profileId].Name;
            return result;
        }catch(Exception e){
            system.debug('Error in fetching user details:'+ e.getMessage());
            return null;
    public class userDetails{
        @AuraEnabled public String profileName;
public class wv6_TruckloadQuoteControllerTest {
    @TestSetup static void createTestData(){
        wv6_TestDataFactory.createAccountRecord();    //create test case & related records
        Account getAccount = [Select Id from Account Limit 1];
        Quote__c quoteTest =new Quote__c();
        insert quoteTest;

    public static testmethod void test_fetchDataOnSubmit(){
        Quote__c quoteTest = [Select Id,Account__c,Origin_Postal_Code_Text__c,Origin_City__c,Origin_State__c,
                              Destination_Postal_Code_Text__c,Destination_City__c, Miles__c, Destination_State__c,
                              Weight__c,Pickup_Date__c from Quote__c Limit 1];
        Test.setMock(HttpCalloutMock.class, new wv6_TruckLoadQuoteRequestMock());
ANUTEJANUTEJ (Salesforce Developers) 
Hi Christi,

The way to make sure the exception handling is also covered is to have raise the exception explicitly from the test class method so as to cover even those lines.

I hope this helps you in addressing your question.

In case if this comes handy can you please choose this as best answer so that it can be used by others in the future if they face a similar issue.