PLATFORM
  • Tails

    Create websites with TailwindCSS

  • Blocks

    Design blocks for your website

  • Wave

    Start building the next great SAAS

  • Pines

    Alpine & Tailwind UI Library

  • Auth

    Plug'n Play Authentication for Laravel

  • Designer comingsoon

    Create website designs with AI

  • DevBlog comingsoon

    Blog platform for developers

  • Static

    Build a simple static website

  • SaaS Adventure

    21-day program to build a SAAS

Written By
Views

Testing HttpCalloutMock In Apex

Testing Single HttpCalloutMock in Apex is pretty straightforward which is described in official docs. If you want to test multiple callout then here is the official docs. So You need to prepare related code base whenever you've something new to test. What if we don't need to write this almost the same code repeatedly? Let's try to design a class that will serve our purpose, that way we don't have to repeat ourselves anymore.

Class: GlobalMock.cls

public class GlobalMock implements HttpCalloutMock {
    public List<Map<String, String>> records {get;set;}

    public GlobalMock(List<Map<String, String>> records) {
        this.records = records;
    }

    public GlobalMock(Map<String, String> sampleMockMap) {
        this.records = new List<Map<String, String>>();
        this.records.add(sampleMockMap);
    }

    public GlobalMock(String endpoint, String method, String body) {
        Map<String, String> sampleMockMap = new Map<String, String>();
        sampleMockMap.put('endpoint', endpoint);
        sampleMockMap.put('method', method);
        sampleMockMap.put('body', body);

        this.records = new List<Map<String, String>>();
        this.records.add(sampleMockMap);
    }

    public HttpResponse respond(HttpRequest req){
        HttpResponse res=new HttpResponse();
        res.setHeader('Content-Type','application/json');
        res.setStatusCode(200);
        for (Map<String, String> record: this.records) {
            if (req.getEndpoint().contains(record.get('endpoint'))) {
                if (record.get('body') != null) res.setBody(record.get('body'));
                System.assertEquals(record.get('method'), req.getMethod());
            }
        }
        return res;
    }
}

Just a regular class that will behave/respond based on your input. By using this class we can test our HttpCallout without ever writing separate code specific for HttpCallout. As you can see the GlobalMock class has three different types of constructors, we can test the HttpCallout in three different ways.

  1. Testing a single endpoint by passing constructor values as strings, in a single line.
Test.setMock(HttpCalloutMock.class, new GlobalMock('https://abc.com/api/v1/token/', 'POST', '{"success":"true"}'));
  1. Testing a single endpoint by passing the constructor value as a Map.
Map<String, String> sampleMockMap = new Map<String, String>();
sampleMockMap.put('endpoint', 'https://abc.com/api/v1/token/');
sampleMockMap.put('method', 'POST');
sampleMockMap.put('body', '{"access":"test"}');
Test.setMock(HttpCalloutMock.class, new GlobalMock(sampleMockMap));
  1. Testing multiple endpoints by passing constructor value as a List of Map.
List<Map<String, String>> sampleMockList = new List<Map<String, String>>();
Map<String, String> sampleMockMap = new Map<String, String>();
sampleMockMap.put('endpoint', 'https://abc.com/api/v1/status/123/delete/?is_instructor=true');
sampleMockMap.put('method', 'DELETE');
sampleMockList.add(sampleMockMap);

Map<String, String> sampleMockMap1 = new Map<String, String>();
sampleMockMap1.put('endpoint', 'https://abc.com/api/v1/status/?customer_id=');
sampleMockMap1.put('method', 'GET');
sampleMockMap1.put('body', '{"count":4,"next":null,"previous":null,"results":[{"id":"d220-9ab6-d5ad3460","customer_id":"123"}]}');
sampleMockList.add(sampleMockMap1);

Map<String, String> sampleMockMap2 = new Map<String, String>();
sampleMockMap2.put('endpoint', 'https://abc/api/v1/token/');
sampleMockMap2.put('method', 'POST');
sampleMockMap2.put('body', '{"access":"test"}');
sampleMockList.add(sampleMockMap2);

Test.setMock(HttpCalloutMock.class, new GlobalMock(sampleMockList));

If you see any pitfalls or if you've any better ideas, please feel free to put your observations.

Comments (0)

loading comments