-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
1Questions
-
1Replies
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);
}
}
-
- Nigel Dendy
- February 17, 2023
- Like
- 0
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);
}
}

- Nigel Dendy
- February 17, 2023
- Like
- 0