Day 18 : Fake callout responses for test classes !

By

3 minutes de lecture

Hello everybody !

Today let’s talk about Apex tests classes in Salesforce. Everyone loves a good test class, and Salesforce makes it official by requiring to have a minimum coverage to deploy Apex code. However, external callouts are not executed when running tests, so there must be a way to test classes that contain external callouts.
In this article, we’ll review the standard ways this is addressed, and show some new feature of the Winter 22′ release.

Callout mocks

To test a method that have an external callout, we need to simulate a response from the service that we call. Indeed, we are trying to test the logic contained in our Apex class and should assume that the service works properly. To simulate an external response, we use a mock that returns a predefined value whenever a callout is made.

The fake external response can be stored or generated in an Apex class, provided it implements the HttpCalloutMock interface. It must then have a method respond like the following:

global class YourHttpCalloutMockImpl implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest req) {
        HTTPResponse response = new HTTPResponse();
        // Create a fake response.
        return response;
    }
}

Then you can initialize your mock object with YourHttpCalloutMockImpl mock = new YourHttpCalloutMockImpl().

An alternative way to create a callout mock is to use a static ressource to store the response data. You first need to create a static ressource that contains your response body, in the format you prefer (JSON, XML). Then you can create your mock like this (careful to match the ‘Content-Type’ parameter with the format of your response) :

StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
mock.setStaticResource('myStaticResourceName');
mock.setStatusCode(200);
mock.setHeader('Content-Type', 'application/json');

After you initialized the object, you can tell your test method you want to use it as a mock using Test.setMock(HttpCalloutMock.class, mock). With both methods (mock class and static ressource), you can set different mocks corresponding to different situations (positive test, negative test, error) in order to test all possible use cases of your Apex class.

Mocks for Salesforce functions

One of the news in the Winter 22′ release is the introduction of Salesforce functions. You can read more about this in a previous article, but for now let’s focus on the fact that it does count as an external callout. This means that any call to a Salesforce function in Apex won’t actually be executed. We need a way to mock a response so we can test our logic. The method to create functions mock is similar to mock class, except you need to implement the interface functions.FunctionInvokeMock.

@isTest
public class FunctionsInvokeMockImpl implements functions.FunctionInvokeMock {
    public functions.FunctionInvocation respond(String functionName, String payload) {
       // return mock success response
       String invocationId = '000000000000000';
       String response = 'mockResponse';
       return functions.MockFunctionInvocationFactory.createSuccessResponse(invocationId, response);       
    }
}

As you can see, the parameters and return type are not the same as for callout mocks, but the way you can tell your test class about which mock to use remains the same:

Test.setMock(functions.FunctionInvokeMock.class, new FunctionInvokeMockImpl());

Summary and references

Futhermor, callout mocks allow us to test our Apex logic despite the external callouts. You can create different mocks corresponding to different test cases. The new feature Salesforce Functions coming with the Winter 22′ counts as external callouts. Thus came with an alternative way to mock functions calls as we presented in this article.

Read more posts

Enforce code standards with PMD

Developers working on a project usually set coding rules to have a standardized codebase. It is an important piece of the code maintainability, and it can be very easy …
March 2023
Advices
Scratch orgs

Uncovering Salesforce Settings: A Step-by-Step Guide for Scratch Orgs

Today, it’s pretty easy to build your Scratch Org definition file when you know what Settings you want to activate, as they are mapped with the same setting names …
February 2023
Advices
Business Analyst

Core qualities of a Business Analyst?

A common definition we are used to hear is that being a Business Analyst means to have a combination of both hard skills and soft skills. What does a …
June 2022
Advices
Image d'illustration d'une employée travaillant sur un ordinateur portable

Process builder and workflow make way to Flows (½)

Overview “If you can do it with a Workflow, then do it with a Process Builder, because everything a Workflow does, a Process Builder does it better”. If you …
March 2022
Advices

Day 22 : Salesforce new “Migrate To Flow tool” in Spring 22

As most of you already know, the workflow rules and process builders are planned to be retired in 2023 (no precise date defined so far). Today, I’m going to …
December 2021
Advices
Wrapped up gifts

Day 13 : CI/CD Salesforce deploys only delta with github actions

Most projects today configure the CI/CD to deploy all metadata from the git repository, even those that haven’t been changed. When you are on a small project, you don’t …
December 2021
Advices