How to Write Test Class for Invokable and @Future Callout?

How to Write Test Class for Invokable and @Future Callout?

On June 30, 2025, Posted by , In Apex,Salesforce Technical Questions, With Comments Off on How to Write Test Class for Invokable and @Future Callout?
How to Write Test Class for Invokable and @Future Callout

Question:

I’m new to Apex and trying to learn as much as possible. I have two Apex classes that are working fine in my org.

The first class is an Invokable Apex class. This class is triggered by a Process Builder when certain conditions are met on the Lead object. It sends the lead’s information (ID, email, first name, and last name) to another class that handles the @Future callout.

The second class is the @Future callout class, which makes a POST request to an external REST API, sending the lead data. The external system returns an ID, which is then used to update the lead record.

Although both classes are functioning correctly, I’m struggling to write the test class for them as I’ve never written Apex test classes before.
Here are the two classes:

1. Invokable Apex Class:

public class MakeCallout {

    @InvocableMethod
    public static void invokeleadcallout(list<Lead> Leads) {
        // Call the future method
        WS_Lead.Notification(Leads[0].id, Leads[0].Email, Leads[0].Firstname);
    }
}

2. WS Callout Class:

global class WS_Lead {
    @future (callout=true)
    public static void Notification(id lid, String name) {
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();

        req.setEndpoint('https://google.com');
        req.setMethod('POST');
        req.setHeader('Content-Type','application/x-www-form-urlencoded');
        req.setBody('name='+EncodingUtil.urlEncode(name, 'UTF-8'));
        req.setTimeout(120000);

        try {
            res = http.send(req);
            System.debug(res.getbody());

            Dom.Document docx = new Dom.Document();
            docx.load(res.getbody());
            Dom.XmlNode xroot = docx.getRootElement();
            String U_Id = xroot.getAttributeValue('U_Id', null);
            System.debug(U_Id);

            Lead le = new Lead(id=lid);
            le.ID__c = U_Id;
            update le;
        } catch (System.CalloutException e) {
            System.debug('Callout error: ' + e);
            System.debug(res.toString());
            res.getbody();
        }
    }
}

Can anyone provide a proper way to write a test class for these two Apex classes?

Answer:

To test Apex classes that involve HTTP callouts and future methods, you need to use a combination of the @isTest annotation, Test.startTest(), Test.stopTest(), and mocking HTTP responses using HttpCalloutMock. Below is an example of how to test both the Invokable method and the @Future callout method:

Boost your Salesforce career with top-notch Salesforce training in Australia, offering hands-on projects and expert guidance for both beginners and professionals.

Test Class:

@isTest class MakeCalloutTest {

    // Mock class to simulate HTTP response
    class EchoHttpMock implements HttpCalloutMock {
        HttpResponse res;
        EchoHttpMock(HttpResponse r) {
            res = r;
        }
        // This is the HttpCalloutMock interface method
        public HttpResponse respond(HttpRequest req) {
            return res;
        }
    }

    @isTest static void test() {
        // Avoid using live data in tests
        List<Lead> leads = new List<Lead>{ new Lead(LastName='Test', Company='test') };
        insert leads;

        // Define the mock response for the HTTP callout
        HttpResponse res = new HttpResponse();
        res.setBody('<?xml version="1.0" encoding="utf-8"?><root U_Id="12345"></root>');
        res.setStatusCode(200);

        // Set the mock response for the callout
        Test.setMock(HttpCalloutMock.class, new EchoHttpMock(res));

        // Start the test execution
        Test.startTest();
        // Enqueue the future call
        MakeCallout.invokeleadcallout(leads);
        // Trigger future method execution
        Test.stopTest();

        // Verify the results
        leads = [SELECT Id__c FROM Lead];
        System.assertEquals('12345', leads[0].Id__c);
    }
}

Explanation:

  1. HttpCalloutMock: A mock class is created to simulate the HTTP response from the external service. The mock class implements the HttpCalloutMock interface and provides the response when a callout is made.
  2. Test.setMock: This method sets the mock class that simulates the HTTP response. You define what the response should look like, including the body and status code. In this example, the response body is an XML containing a U_Id.
  3. Test.startTest() and Test.stopTest(): These methods are used to enclose the actual method calls being tested. Test.startTest() starts the test, and Test.stopTest() ensures that the future method is executed within the test context.
  4. Assert Statements: After running the test, you verify if the lead’s custom field (Id__c) was correctly updated with the U_Id returned from the external API.

Key Notes:

  • This test class does not cover the exception handling part of the try-catch block. To fully test the callout, you can manually trigger a CalloutException in the mock class to simulate the error scenario.
  • The test ensures that the lead record is updated with the U_Id returned from the external system.

This approach helps you simulate callouts in your tests and properly validate that your @Future methods and Invocable methods work as expected without actually making live callouts.

Launch Your Salesforce Career with Expert Training in Australia

Take your career to new heights with professional Salesforce training in Australia from CRS Info Solutions. Designed to equip you with the skills needed to thrive in the fast-growing Salesforce ecosystem, our courses focus on practical learning with real-time project experience. From Salesforce Admin and Developer to cutting-edge AI modules, we cover it all with hands-on training led by industry experts.

Whether you’re a beginner exploring the Salesforce training in Australia or an experienced professional looking to upgrade your skills, our training is tailored to meet your career goals. With personalized support, in-depth course materials, and expert guidance for certification and interview preparation, you’ll be fully prepared to excel in the industry.

Join us today for a free demo session and take the first step towards a rewarding Salesforce career!!!

See Also : What are classes in Apex programming?

What is a Map class in Salesforce Apex? with examples

Comments are closed.