TrueSolv β€” Header Component
Home >> How to's >> How to write Unit Tests with Service Locator

How to write Unit Tests with Service Locator

Service Locator Pattern salesforce truesolv

TheΒ service locator patternΒ is aΒ design patternΒ used inΒ software developmentΒ to encapsulate the processes involved in obtaining a service with a strongΒ abstraction layer.

We already mention it in our article: How to develop a flexible Apex code for Salesforce.

This pattern uses a central registry known as the “service locator”, which on request returns the information necessary to perform a certain task. The approach simplifies component-based applications where all dependencies are listed at the beginning of the whole application design, consequently making traditional dependency injection a more complex way of connecting objects.

For example, you need to write a unit test for RequestSender class that performs a callout to web service.

Copy to clipboard
public class RequestSender {

    public String getGooglePage() {
        HttpRequest request = new HttpRequest();
        request.setMethod('GET');
        request.setEndpoint('https://www.google.com/');
        Http sender = new Http();
        HttpResponse response = sender.send(request);
        if (response.getStatusCode() == 200) {
            return response.getBody();
        }
        return null;
    }
}

First of all that you need to do is implementΒ getInstanceΒ method to create an instance of the class throughΒ ServiceLocatorΒ to give ServiceLocator the ability to putΒ RequestSenderΒ to the registry.

Β 

Then you need to refactor a current method and extract a new one method to send Http Request (sendRequest) and make it and the whole class virtual to give the ability to change the behavior of the method.

Copy to clipboard
public virtual class RequestSender {

    public static RequestSender getInstance() {
        return (RequestSender)
            ServiceLocator.getInstance(RequestSender.class);
    }

    public virtual HttpResponse sendRequest(HttpRequest request) {
        Http sender = new Http();
        return sender.send(request);
    }

    public String getGooglePage() {
        HttpRequest request = new HttpRequest();
        request.setMethod('GET');
        request.setEndpoint('https://www.google.com/');
        HttpResponse response = sendRequest(request);
        if (response.getStatusCode() == 200) {
            return response.getBody();
        }
        return null;
    }
}

To cover the class by unit tests you need to implementΒ FakeRequestSenderΒ that will extendΒ RequestSenderΒ andΒ overrideΒ the behavior ofΒ sendRequestΒ the method, because we can’t perform callouts in the unit tests.

Copy to clipboard
@isTest
public class RequestSenderTest {

    @isTest
    static void getGooglePageWithServiceLocatorTest() {
        ServiceLocator.setMock(RequestSender.class, 
            FakeRequestSender.class);
        String body = RequestSender.getInstance().getGooglePage();
        System.assertEquals('GOOGLE', body);
    }

    public class FakeRequestSender extends RequestSender {
        public override HttpResponse sendRequest(HttpRequest request) {
            HttpResponse response = new HttpResponse();
            response.setStatusCode(200);
            response.setBody('GOOGLE');
            return response;
        }
    }
}

Then you need to set it in Service Locator using ServiceLocator.setMock (RequestSender.class, FakeRequestSender.class);

Service Locator will give you an ability to override any behavior in any method in the class that helps you to write unit tests quickly and efficiently.

Free Consultation

Ready to solve your Salesforce challenges?

Get a free consultation with our certified Salesforce experts. No commitment required.

See our packages β†’
TrueSolv β€” Footer Component