You need to sign in to do that
Don't have an account?
Nigel Dendy
How to Create a Test class with a Future Callout that is not dependent on an HTTP Response?
I am new to Apex, but I have been tasked with sending a Salesforce Custom Object to another Company system. My Class works as expected, but my test class fails due to having a @future method. I did look into the Mock callout classes but those seem to be aimed at getting a fake response but I don't really have any logic based around the response.
My Test Class code coverage is only at 4% because my createRecord method calls the sendCase method which has the Http Callout in it.
So my question is: Do I write the Mock Class for the 'sendCase` method? Or will I need to completely refactor my code?
Any help would be greatly appreciated .
Reference Links
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_testing_httpcalloutmock.htm
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_wsdl2apex_testing.htm
https://hicglobalsolutions.com/blog/how-to-create-a-mock-callout-to-test-the-apex-rest-callout-in-salesforce/
My Class
My Test Class
My Test Class code coverage is only at 4% because my createRecord method calls the sendCase method which has the Http Callout in it.
So my question is: Do I write the Mock Class for the 'sendCase` method? Or will I need to completely refactor my code?
Any help would be greatly appreciated .
Reference Links
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_testing_httpcalloutmock.htm
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_wsdl2apex_testing.htm
https://hicglobalsolutions.com/blog/how-to-create-a-mock-callout-to-test-the-apex-rest-callout-in-salesforce/
My Class
public without sharing class Processmaker_CreateSiteSurvey { public string endpoint; public string pro_uid; public string tas_uid; public Processmaker_CreateSiteSurvey() { //endpoint = 'https://<redacted>/api/1.0/workflow/cases'; // Prod Processmaker Endpoint endpoint = 'https://<redacted>/api/1.0/workflow/cases'; // Dev Processmaker Endpoint pro_uid = '308138621584f0518bd8f89094895074'; tas_uid = '562545883584f060a62b559007702299'; } /*----------------------------------------- createRecord() - - Invocable Method This methods builds a ProcessMaker case using the invocable variable -----------------------------------------*/ @InvocableMethod (label='Create a New Site Survey') public static void createRecord(List<Create_Case_Params> params) { Processmaker_CreateSiteSurvey p0 = new Processmaker_CreateSiteSurvey(); PM_SiteSurvey cs1 = new PM_SiteSurvey(); PM_SiteSurvey.Variables cv1 = new PM_SiteSurvey.Variables(); List<PM_SiteSurvey.Variables> lcv1 = new List<PM_SiteSurvey.Variables>(); Processmaker_Case__c fc1 = new Processmaker_Case__c(); String recordTypeID = [Select Id FROM RecordType WHERE Name = 'Business Site Survey'].Id; //Salesforce Field Check Record for (Create_Case_Params param: params) { String servSelected = string.join(param.surveySelection, ';'); fc1.Survey_Selection_s__c = servSelected; fc1.SF_User__c = param.lookupUser; fc1.SF_Contact__c = param.lookupContact; fc1.SF_Account__c = param.lookupAccount; fc1.Service_Rep__c = param.origName; fc1.Contact_Number__c = param.contactNum; fc1.Service_Area__c = param.serviceArea; fc1.Submitted_Date__c = param.submitDate; fc1.Site_Survey_Scheduled__c = param.sssDate; fc1.Site_Survey_Scheduled_Time__c = param.sssTime; fc1.Business_Name__c = param.busName; fc1.Business_Address__c = param.busAddy; fc1.Local_Contact__c = param.localContact; fc1.Local_Contact_Phone__c = param.localContactPhone; fc1.Other__c = param.surveySelectionOther; fc1.Remarks__c = param.remarks; fc1.RecordTypeId = recordTypeID; } try { insert fc1; } catch (StringException e) { System.debug('An error has occurred: ' + e.getMessage()); } //Processmaker Field Check Array for (Create_Case_Params param: params) { cs1.pro_uid = p0.pro_uid; cs1.tas_uid = p0.tas_uid; cv1.CustomerSvcFullName = param.origName; cv1.CustomerSvcPhone = param.contactNum; cv1.ServiceArea = param.serviceArea; cv1.ServiceArea_label = param.serviceArea_label; //label cv1.SubmitDate = param.submitDate; cv1.SubmitDate_label = param.subDate_label; //label cv1.ScheduledSiteSurveyDate = param.sssDate; cv1.ScheduledSiteSurveyDate_label = param.siteSurveySched_label; //label cv1.ScheduledSiteSurveyTime = param.sssDate + ' ' + param.sssTime; cv1.ScheduledSiteSurveyTime_label = param.sssTime; cv1.BusinessName = param.busName; cv1.BusinessAddress = param.busAddy; cv1.BusinessLocalContact = param.localContact; cv1.BusinessContactTelephone = param.localContactPhone; cv1.SurveySelection = param.surveySelection; String surveySelection_label = json.serialize(param.surveySelection_label); cv1.SurveySelection_label = surveySelection_label; //label cv1.SelectionOther = param.surveySelectionOther; cv1.SelectionOther_label = param.surveySelectionOther; cv1.RequestRemarks = param.remarks; cv1.SalesforceRecordID = fc1.Id; cv1.CustomerSvcUserID = [SELECT SamAccountName__c FROM User WHERE Id = :param.lookupUser].SamAccountName__c; lcv1.add(cv1); cs1.variables = lcv1; } sendCase(json.serialize(cs1), fc1.Id); } /*----------------------------------------- sendCase() - returns ProcessMaker Response This method send the case to Processmaker via HTTP POST Request -----------------------------------------*/ @future(callout = true) public static void sendCase(String payload, String recordID) { Processmaker_CreateSiteSurvey p1 = new Processmaker_CreateSiteSurvey(); String access_token = Processmaker_Connector.getloginToken(); try { HttpRequest req = new HttpRequest(); req.setMethod('POST'); req.setEndpoint(p1.endpoint); req.setHeader('Content-Type', 'application/json; charset=utf-8'); req.setHeader('Authorization', 'Bearer ' + access_token); req.setBody(payload); Http binding = new Http(); HttpResponse res = binding.send(req); ProcessmakerResponse pr1 = (ProcessmakerResponse) JSON.deserialize(res.getBody(), ProcessmakerResponse.class); Processmaker_ExecuteTrigger.executeTrigger(pr1.app_uid, '478587874638e4d6b391802022646525'); Processmaker_RouteCase.routeCase(pr1.app_uid); Processmaker_Case__c caseRecord = new Processmaker_Case__c( Id = recordID, app_uid__c = pr1.app_uid, Case_Number__c = pr1.app_number ); upsert caseRecord; System.debug('Case Creation Successful'); } catch (StringException e) { System.debug('An error has occurred: ' + e.getMessage()); } } /*---------------------------------------------- Create Case Params - Class - Invocable Variables This class houses all of the invocalble variables for the createCase() invocable method ----------------------------------------------*/ public class Create_Case_Params { @InvocableVariable(label='Originator Name' required=true) public String origName; @InvocableVariable(label='Contact Number' required=true) public String contactNum; @InvocableVariable(label='Service Area' required=true) public String serviceArea; @InvocableVariable(label='Submission Date' required=true) public String submitDate; @InvocableVariable(label='Site Survey Scheduled' required=true) public String sssDate; @InvocableVariable(label='Siter Survey Scheduled (Time)' required=true) public String sssTime; @InvocableVariable(label='Business Name' required=true) public String busName; @InvocableVariable(label='Business Address' required=true) public String busAddy; @InvocableVariable(label='Local Contact for Business' description='must be AptSelectionApartment, AptSelectionSuite, AptSelectionLot, AptSelectionNA' required=true) public String localContact; @InvocableVariable(label='Local Contact Phone' required=true) public String localContactPhone; @InvocableVariable(label='Survey Selection' description='values must be SurveySelectionVoIP, SurveySelectionWiring, SurveySelectionKeySystem, SurveySelectionMETS, SurveySelectionZipstream' required=true) public List<String> surveySelection; @InvocableVariable(label='Survey Selection Other') public String surveySelectionOther; @InvocableVariable(label='Remarks' required=true) public String remarks; //Labels @InvocableVariable(label='Label: Survey Selection') public List<String> surveySelection_label; @InvocableVariable(label='Label: Site Survey Date Scheduled') public String siteSurveySched_label; @InvocableVariable(label='Label: Site Survey Time Scheduled') public String siteSurveySchedTime_label; @InvocableVariable(label='Label: Service Area') public String serviceArea_label; @InvocableVariable(label='Label: Submission Date') public String subDate_label; //Salesforce Fields @InvocableVariable(label='Account' ) public String lookupAccount; @InvocableVariable(label='Contact' ) public String lookupContact; @InvocableVariable(label='User' ) public String lookupUser; } }
My Test Class
@isTest public without sharing class Processmaker_CreateSiteSurveyTest { public Processmaker_CreateSiteSurveyTest() { } //--------Data Generation @isTest public static List<Processmaker_CreateSiteSurvey.Create_Case_Params> createTestData() { //Create a test Account Account testAccount = new Account( Name = 'Salesforce Testing', Phone = '0123456789', BillingStreet = '123 Fake Street', BillingCity = 'Fake City', BillingState = 'Fake State', BillingPostalCode = '12345', BillingCountry = 'Fake Country' ); insert testAccount; //Create a test Contact Contact testContact = new Contact( FirstName = 'Salesforce', LastName = 'Testing', Phone = '0123456789', AccountId = testAccount.Id ); insert testContact; //Get the User, Account and Contact IDs String testSFUser = [SELECT Id FROM User WHERE Name = 'Nigel Dendy'].Id; //Create Case Params List<Processmaker_CreateSiteSurvey.Create_Case_Params> caseParams = new List<Processmaker_CreateSiteSurvey.Create_Case_Params>(); Processmaker_CreateSiteSurvey.Create_Case_Params caseParam = new Processmaker_CreateSiteSurvey.Create_Case_Params(); caseParam.origName = 'Salesforce Testing'; caseParam.contactNum = '0123456789'; caseParam.serviceArea = 'ServiceAreaRKHL'; caseParam.submitDate = '2023-02-16'; caseParam.sssDate = '2023-02-21'; caseParam.sssTime = '08:24'; caseParam.busName = 'TestBusinessName'; caseParam.busAddy = '123 Fake Address'; caseParam.localContact = 'Bob Barker'; caseParam.localContactPhone = '0123456789'; caseParam.surveySelection = new List<String>{'SurveySelectionVoIP','SurveySelectionWiring'}; caseParam.surveySelectionOther = 'CustomRequest'; caseParam.remarks = 'blah blah blah blah blah'; //Labels caseParam.surveySelection_label = new List<String>{'VoIP','Wiring'}; caseParam.siteSurveySched_label = '2023-02-21'; caseParam.siteSurveySchedTime_label = '08:24'; caseParam.serviceArea_label = 'ServiceAreaRKHL'; caseParam.subDate_label = '2023-02-16'; //Salesforce Fields caseParam.lookupAccount = testAccount.Id; caseParam.lookupContact = testContact.Id; caseParam.lookupUser = testSFUser; caseParams.add(caseParam); return caseParams; } //--------Tests @isTest public static void Processmaker_CreateSiteSurveyTest() { Processmaker_CreateSiteSurvey testClass = new Processmaker_CreateSiteSurvey(); } @isTest public static void createCaseTest() { List<Processmaker_CreateSiteSurvey.Create_Case_Params> testClass = createTestData(); Processmaker_CreateSiteSurvey.createRecord(testClass); } }
To create a test class with a future callout that is not dependent on an HTTP response, you can use the Test.setMock method to set a mock response for the callout. This allows you to simulate the callout without actually making the HTTP request.
If you find my answer helpful, please mark it as the best answer.Thanks!
All Answers
To create a test class with a future callout that is not dependent on an HTTP response, you can use the Test.setMock method to set a mock response for the callout. This allows you to simulate the callout without actually making the HTTP request.
If you find my answer helpful, please mark it as the best answer.Thanks!