I am a total beginner in Apex, however I created the following class that calls an external API endpoint and is invoked by a flow:
public class SubscribeToStatuspage {
@InvocableMethod(label='Call Status Page' description='Subscribe the contact to status page' category='Contact' callout=true)
public static void callStatusPageAPI(List<ID> contactIDs) {
// Get the contact details
List<Contact> contacts = [SELECT Name, Email FROM Contact WHERE Id in :contactIDs];
String contactName;
String contactEmail;
for (Contact contact : contacts) {
contactName = contact.Name;
contactEmail = contact.Email;
Http http = new Http();
HttpRequest tokenRequest = new HttpRequest();
// First request an auth token with the refresh token
tokenRequest.setEndpoint('https://accounts.zoho.com/oauth/v2/token?');
tokenRequest.setMethod('POST');
tokenRequest.setBody('client_id=XXX&refresh_token=XXX&grant_type=refresh_token');
HttpResponse tokenResponse = http.send(tokenRequest);
//Parse the response to get the auth token
JSONParser parser = JSON.createParser(tokenResponse.getBody());
String accessToken;
while (parser.nextToken() != null) {
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'access_token')){
parser.nextToken();
accessToken = parser.getText();
}
}
// Use the access token to subscribe the user
HttpRequest subscribeRequest = new HttpRequest();
subscribeRequest.setEndpoint('https://www.site24x7.com/sp/api/subscribers/email');
subscribeRequest.setMethod('POST');
subscribeRequest.setHeader('Content-Type', 'application/json;charset=UTF-8');
subscribeRequest.setHeader('Accept', 'application/json; version=2.0');
subscribeRequest.setHeader('Authorization', 'Zoho-oauthtoken ' + accessToken);
JSONGenerator jsonBody = JSON.createGenerator(true);
jsonBody.writeStartObject();
jsonBody.writeStringField('subscriber_name', contactName);
jsonBody.writeStringField('email_id', contactEmail);
jsonBody.writeStringField('subscribe_statuspage_info','{"enc_statuspage_id":"XXX"}');
jsonBody.writeEndObject();
String jsonS = jsonBody.getAsString();
subscribeRequest.setBody(jsonS);
//subscribeRequest.setBody('{"subscriber_name": + contactName, "email_id": + contactEmail, "subscribe_statuspage_info": {"enc_statuspage_id":"XXX"}}');
HttpResponse subscribeResponse = http.send(subscribeRequest);
System.debug(subscribeResponse.getBody());
}
}
}
This works fine, but I'm stuck writing the proper test class for it. I got this far:
@isTest
private class SubscribeToStatuspageTest{
@testSetup
static void setupTestData(){
test.startTest();
Contact contact_Obj = new Contact(LastName = 'LastName835', Email = 'Email41@test.com', HasOptedOutOfEmail = false, HasOptedOutOfFax = false, DoNotCall = false, Christmas_Card__c = false, Newsletter_Opt_In2__c = false, CSM_contact__c = false, Active__c = false, Main_contact__c = false, Email_opt_in_via_website_newsletter__c = false, Opt_in_after_bounce__c = false, Escalation_contact__c = false, Release_contact__c = false, Buyer_contact__c = false, Billing_contact__c = false, SSP_User__c = false, Security_contact__c = false, dupcheck__dc3DisableDuplicateCheck__c = false, Customer_panel_member__c = false, Personal_Data_Breach_Contact__c = false, TK_Double_Opt_In__c = false);
Insert contact_Obj;
test.stopTest();
}
static testMethod void test_callStatusPageAPI_UseCase1(){
List<Contact> contact_Obj = [SELECT Id,Name,Email,HasOptedOutOfEmail,HasOptedOutOfFax,DoNotCall,Christmas_Card__c,Newsletter_Opt_In2__c,CSM_contact__c,Active__c,Main_contact__c,Email_opt_in_via_website_newsletter__c,Opt_in_after_bounce__c,Escalation_contact__c,Release_contact__c,Buyer_contact__c,Billing_contact__c,SSP_User__c,Security_contact__c,dupcheck__dc3DisableDuplicateCheck__c,Customer_panel_member__c,Personal_Data_Breach_Contact__c,TK_Double_Opt_In__c from Contact];
System.assert(contact_Obj.size()>0);
SubscribeToStatuspage obj01 = new SubscribeToStatuspage();
SubscribeToStatuspage.callStatusPageAPI(new List<ID>());
}
}
This succeeds, however the code coverage is only 14% because the test never enters the for loop. What am I missing here?
Any advise would be very much appreciated. Thank you!
testmethod
keyword is deprecated, and you should use the@isTest
annotation instead. Also, your test will need to mock the callout. See How do I unit test code that includes a callout for more details.