0

I am having an issue with getting my trigger and two classes from sandbox to production. I have one trigger that kicks off on an update to the account object that calls one of two classes to authenticate and post data to our endpoint. This runs fine and dandy from Sandbox to our system. I found some examples of setting up test classes for the trigger and callouts, but cannot get past the 50% code coverage. The test of the two callout classes run 16 of 31 lines and the trigger runs 13 of 28 lines. The test of the trigger also returns an error "Methods defined as TestMethod do not support Web service callouts". I thought I would be able to bypass these issues with the test classes. I have included the code for all below and would appreciate it if I can be told/guided in what should be done to get this up to production.

This is the result of the test: enter image description here

Trigger:

trigger AccountUpdate on Account (after update) {

    String buildMessage;
   
    for(Account a:Trigger.new){
        if (a.RecordTypeId == '0125Y000001GTK4QAO')    //buisness accounts only
        {    
            buildMessage = '{';    
            buildMessage = buildMessage + '"BillingCity": "' + a.BillingCity + '"'; 
            buildMessage = buildMessage + ', "BillingPostalCode":' + '"' + a.BillingPostalCode + '"';
            buildMessage = buildMessage + ', "BillingState":' + '"' + a.BillingState + '"';
            buildMessage = buildMessage + ', "BillingStreet":' + '"' + a.BillingStreet + '"';
            buildMessage = buildMessage + ', "Phone":' + '"' + a.Phone + '"';
            buildMessage = buildMessage + ', "Facility_c":' + '"' + a.Facility__c + '"';
            buildMessage = buildMessage + ', "Name":' + '"' + a.Name + '"';
            buildMessage = buildMessage + '}';
            AccountDestinationCallout.putDestination(buildMessage);  
        }else if (a.RecordTypeId == '0125Y000001GTKOQA4'){    //person accounts only  
            buildMessage = '{';    
            buildMessage = buildMessage + '"Name":' + '"' + a.Name + '"';
            buildMessage = buildMessage + ', "MRN__c":' + '"' + a.MRN__c + '"';
            buildMessage = buildMessage + ', "PersonBirthdate":' + '"' + a.PersonBirthdate + '"';
            buildMessage = buildMessage + ', "PersonEmail":' + '"' + a.PersonEmail + '"';
            buildMessage = buildMessage + ', "PersonHomePhone":' + '"' + a.PersonHomePhone + '"';
            buildMessage = buildMessage + ', "PersonMailingCity":' + '"' + a.PersonMailingCity + '"';
            buildMessage = buildMessage + ', "PersonMailingPostalCode":' + '"' + a.PersonMailingPostalCode + '"';
            buildMessage = buildMessage + ', "PersonMailingState":' + '"' + a.PersonMailingState + '"';            
            buildMessage = buildMessage + ', "PersonMailingStreet":' + '"' + a.PersonMailingStreet + '"';
            buildMessage = buildMessage + ', "RecordTypeId":' + '"' + a.RecordTypeId + '"';            
            buildMessage = buildMessage + ', "Account__c":' + '"' + a.Account__c + '"';
            buildMessage = buildMessage + '}';            
            AccountContactCallout.putContact(buildMessage);  
        }    
    }   
}

First class:

public class AccountContactCallout {
    public static String generatedToken {set; get;}
    static String errorMessage {set; get;}
    static String TimelineResponse {set; get;}
    
    @future(callout = true)
    
// called by trigger AccountUpdate
    
    public static void putContact(string buildMessage) {    
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');
        req.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf('clientid' + ':' + 'clienttoken')));
        req.setHeader('content-type', 'application/x-www-form-urlencoded');
        req.setEndpoint('https://ourdomain.com/token');
        req.setBody('grant_type=client_credentials');

        Http http = new Http();

        HTTPResponse res = http.send(req);
        JSONParser objParse = JSON.createParser(res.getBody());
        while (objParse.nextToken() != null) 
        {
           if (objParse.getCurrentToken() == JSONToken.FIELD_NAME && objParse.getText() == 'access_token')
           {                               
              objParse.nextToken();
              generatedToken = objParse.getText();
           }
        }
            if(generatedToken == null ) 
            {
                TimelineResponse = 'Error while generating token, so unable to get messages. Check your debug log.';
                return;
            }

            HttpRequest objReq = new HttpRequest();
        objReq.setEndpoint('https://ourdomain.com/postSF1');
            objReq.setMethod('POST');
            objReq.setHeader('Authorization', 'Bearer ' + generatedToken);
            objReq.setBody(buildMessage);
            Http objHttp = new Http();
            HTTPResponse objRes = objHttp.send(objReq);
            TimelineResponse = objRes.getBody();
            if(String.isBlank(TimelineResponse))
            {
               TimelineResponse = objRes.toString();
            }
    }
}

Second class:

public class AccountDestinationCallout {
    public static String generatedToken {set; get;}
    static String errorMessage {set; get;}
    static String TimelineResponse {set; get;}
    
    @future(callout = true)
    
// called by trigger AccountUpdate
    
    public static void putDestination(string buildMessage) {    
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');
        req.setHeader('Authorization', 'Basic ' + EncodingUtil.base64Encode(Blob.valueOf('clientid' + ':' + 'clienttoken')));
        req.setHeader('content-type', 'application/x-www-form-urlencoded');
        
        req.setEndpoint('https://ourdomain.com/token');
        req.setBody('grant_type=client_credentials');

        Http http = new Http();

        HTTPResponse res = http.send(req);
        JSONParser objParse = JSON.createParser(res.getBody());
        while (objParse.nextToken() != null) 
        {
           if (objParse.getCurrentToken() == JSONToken.FIELD_NAME && objParse.getText() == 'access_token')
           {                               
              objParse.nextToken();
              generatedToken = objParse.getText();
           }
        }
            if(generatedToken == null ) 
            {
                TimelineResponse = 'Error while generating token, so unable to get messages. Check your debug log.';
                return;
            }

            HttpRequest objReq = new HttpRequest();
        objReq.setEndpoint('https://ourdomain.com/postS2');
            objReq.setMethod('POST');
            objReq.setHeader('Authorization', 'Bearer ' + generatedToken);
            objReq.setBody(buildMessage);
            Http objHttp = new Http();
            HTTPResponse objRes = objHttp.send(objReq);
            TimelineResponse = objRes.getBody();
            if(String.isBlank(TimelineResponse))
            {
               TimelineResponse = objRes.toString();
            }
    }
}

Trigger test:

@isTest
private class TestAccountUpdate {
@isTest static void TestUpdateAccount() {
        // Test data setup
        // Create an account with an opportunity, and then try to delete it
        Account acct = new Account(Name='Test Account', RecordTypeId = '0125Y000001GTK4QAO');
    
        insert acct;
        
        // Perform test
        Test.startTest();
        Database.update(acct, false);
        Test.stopTest();

       Account acct2 = new Account(Name='Test Account', RecordTypeId = '0125Y000001GTKOQA4');
    
        insert acct2;
        
        // Perform test
        Test.startTest();
        Database.update(acct2, false);
        Test.stopTest();
    }
}

First class test:

@isTest
private class TestCallout {
@isTest static void testCalloutWithStaticResources() {
        // Use StaticResourceCalloutMock built-in class to
        // specify fake response and include response body 
        // in a static resource.
        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
        mock.setStaticResource('APEXCALLOUTTEST');
        mock.setStatusCode(200);
        mock.setHeader('Content-Type', 'application/json');
        
        // Set the mock callout mode
        Test.setMock(HttpCalloutMock.class, mock);
        
        // Call the method that performs the callout
        AccountDestinationCallout.putDestination(
            'example text');    
}
}

Second class test:

@isTest
public class TestCallout2 {
@isTest static void testCalloutWithStaticResources() {
        // Use StaticResourceCalloutMock built-in class to
        // specify fake response and include response body 
        // in a static resource.
        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
        mock.setStaticResource('APEXCALLOUTTEST');
        mock.setStatusCode(200);
        mock.setHeader('Content-Type', 'application/json');
        
        // Set the mock callout mode
        Test.setMock(HttpCalloutMock.class, mock);
        
        // Call the method that performs the callout
        AccountContactCallout.putContact(
            'example text');   
}
}
1
  • Before getting this code in production, you should be more worried about how your code is not bulkified, how it uses hardcoded ID values, how it can break because you're not properly encoding your JSON, how you're inefficiently parsing your JSON, how your unit tests are not asserting proper behavior, how your unit tests can fail silently, etc.
    – sfdcfox
    Nov 2, 2021 at 20:56

1 Answer 1

0

I finally found what I needed...here is the new test class:

@isTest
public class AccountUpdateTest {
@isTest static void testCallout1() 
    {
    Account tmp = new Account(LastName = 'ACME', RecordTypeId = '0125Y000001GTKOQA4');
    insert tmp;

        Account accountToUpdate;
        accountToUpdate = 
        [SELECT LastName FROM Account 
         WHERE RecordTypeId = '0125Y000001GTKOQA4'
         LIMIT 1];

    accountToUpdate.LastName = 'UpdateTest';
    // Make the update call.

        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        Test.startTest();
        update accountToUpdate;  
        Test.stopTest();     
    }

@isTest static void testCallout2() 
    {
    Account tmp2 = new Account(Name = 'ACME2', RecordTypeId = '0125Y000001GTK4QAO');
    insert tmp2;  
        
Account accountToUpdate;        
        accountToUpdate = 
        [SELECT Name FROM Account 
         WHERE RecordTypeId = '0125Y000001GTK4QAO'
         LIMIT 1];

    accountToUpdate.Name = 'UpdateTest2';
    // Make the update call.        

        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        Test.startTest();
        update accountToUpdate;  
        Test.stopTest();
   
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .