How to create mock class for multiple Callouts in single class

This need is covered in Testing Apex Callouts using HttpCalloutMock. Specifically, see the Testing multiple HTTP callouts section. Here's the example they use:

public class MultiRequestMock implements HttpCalloutMock {
    Map<String, HttpCalloutMock> requests;

    public MultiRequestMock(Map<String, HttpCalloutMock> requests) {
        this.requests = requests;
    }

    public HTTPResponse respond(HTTPRequest req) {
        HttpCalloutMock mock = requests.get(req.getEndpoint());
        if (mock != null) {
            return mock.respond(req);
        } else {
                throw new MyCustomException('HTTP callout not supported for test methods');
        }
    }

    public void addRequestMock(String url, HttpCalloutMock mock) {
        requests.put(url, mock);
    }
}

I'm not sure why they don't annotate the class as @IsTest. You probably should.


Here is perhaps the simplest form of a mock that deals with multiple requests.

It is declared as an inner class of the test class so the idea is that it handles all the cases that the outer test class handles. In the respond method you can look at the endpoint of the request or the body of the request and use if/else logic to return the appropriate fake response. (You can also add asserts to verify the details of the request body.)

@IsTest
private class CalloutTest {

    private class Mock implements HttpCalloutMock {
        public HTTPResponse respond(HTTPRequest req) {
            if (req.getEndpoint().endsWith('abc')) {
                HTTPResponse res = new HTTPResponse();
                res.setBody('{}');
                res.setStatusCode(200);
                return res;
            } else if (req.getEndpoint().endsWith('xyz')) {
                ...
            } else {
                System.assert(false, 'unexpected endpoint ' + req.getEndpoint());
                return null;
            }
        }
    }

    @IsTest
    static void abc() {
        Test.setMock(HttpCalloutMock.class, new Mock());
        ...
    }

    @IsTest
    static void xyz() {
        Test.setMock(HttpCalloutMock.class, new Mock());
        ...
    }
}