function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
ACN ConnectACN Connect 

How to create Mock test methods for an Apex class that contains a method with a return type as void?

First, see the below example that I have taken from trailhead modules.

public class AnimalsCallouts {
 
    public static HttpResponse makePostCallout() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('POST');
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        request.setBody('{"name":"mighty moose"}');
        HttpResponse response = http.send(request);
        // Parse the JSON response
        if(response.getStatusCode() != 201) {
            System.debug('The status code returned was not expected: ' +
                response.getStatusCode() + ' ' + response.getStatus());
        } else {
            System.debug(response.getBody());
        }
        return response;
    }        
}
@isTest
global class AnimalsHttpCalloutMock implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest request) {
        // Create a fake response
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}');
        response.setStatusCode(200);
        return response; 
    }
}
@isTest 
static void testPostCallout() {
    // Set mock callout class 
    Test.setMock(HttpCalloutMock.class, new AnimalsHttpCalloutMock()); 
    // This causes a fake response to be sent
    // from the class that implements HttpCalloutMock. 
    HttpResponse response = AnimalsCallouts.makePostCallout();
    // Verify that the response received contains fake values
    String contentType = response.getHeader('Content-Type');
    System.assert(contentType == 'application/json');
    String actualValue = response.getBody();
    System.debug(response.getBody());
    String expectedValue = '{"animals": ["majestic badger", "fluffy bunny", "scary bear", "chicken", "mighty moose"]}';
    System.assertEquals(expectedValue, actualValue);
    System.assertEquals(200, response.getStatusCode());
}

Here in the above case, we are faking our response in Mock class so whenever the test class method is going to call our apex class we are going to receive a mocked response which we going to put in assertion with our expected response. 

In our project, apex classes contain a future method with the return type as void (actually they are getting called by triggers to post something externally whenever a record is created in salesforce). So in that case, is there a way to receive a fake response in test class when my apex class methods return nothing? (Assume below as my project classes)

public class AnimalsCallouts {
 
    public static void makePostCallout() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint(...);
        request.setMethod('POST');
        request.setBody(...);
        HttpResponse response = http.send(request);
        if(response.getStatusCode() != 201) {
            System.debug('...');
        } else {
            System.debug('...');
        }
    }        
}
@isTest
global class AnimalsHttpCalloutMock implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest request) {
        ....
        ....
        return response; 
    }
}
@isTest 
static void testPostCallout() {
    Test.setMock(HttpCalloutMock.class, new AnimalsHttpCalloutMock()); 
    HttpResponse response = AnimalsCallouts.makePostCallout(); (i can't recieve this inside a variable because method is returning nothing.)
    String actualValue = response.getBody();
    String expectedValue = '....';
    System.assertEquals(expectedValue, actualValue);
}
TobyKutlerTobyKutler
If a method is void then it has no output therefore not possible to mock. You can only mock data. Just call the post method from your test class and that should get you full coverage. What you are looking to do with the potential assertion is an integration test which is not necessary. When writing Test Classes we want to separate the database from the application. The application we need to test not the database. You can read more on integration tests vs unit tests here (https://www.apexhours.com/pure-unit-testing-in-apex/)