Development, Salesforce

Mocking and testing outbound web service calls in Salesforce

The Salesforce platform is great when you want to quickly build applications because it will give you a lot of functionality for free. As a developer on the platform, I have often worked on building real-time integrations on other systems. These are usually implemented by writing a web service call out from a trigger. The platform requires you to write test code that should have at least 75% line coverage. This is, of course, a great opportunity for us to write proper test code.

When test code is executed, it will prevent the system from doing outbound calls, which in turn prevents any unintended interaction with external systems. But how do you then do testing? Mocking is the answer.

A mock is a class that will receive your outbound request instead of the request being sent to an external system. This class simulates the behavior of the real system, which means you can simulate both successful and failed responses. An additional bonus is that you can develop code without having real access to the external system; you can rely on the mock. This is test-driven development at its core.

To create your mock, you need to create a class that is global and implements the WebServiceMock class. For example:

@isTest
global class MyWebServiceMock implements WebServiceMock {

    global void doInvoke(Object stub, Object request, Map<String, Object> response, String endpoint, String soapAction, String requestName, String responseNS, String responseName, String responseType) {

    }

}

The doInvoke() method parameters are as follows:

Do you like the content on this page? Sign up for our newsletter
to make sure you are not missing out!

Parameter Description
Object Stub Instance of the auto-generated class
Object Request SOAP web service request being invoked
Map<string, object> Response Collection of key/value pairs to send as the response to the request
String Endpoint Endpoint for the request
String soapAction Request SOAP action
String requestName Request SOAP operation name
String responseNS Response namespace
String responseName Name of the response element (WSDL)
String responseType Class for the response

In the Request parameter, you will find the data sent to the web service. This object will need to be cast to the right data type. You will find this data type by looking in the proxy class generated by wsdl2apex. The mock is responsible for creating a response by generating and populating the Response map. Again, by looking at the generated proxy class, you will be able to find out which data type and what keys and values you should use. Your mock can, of course, throw exceptions to simulate failures.

When you use WebServiceMock, all outbound requests will go to the mock. If you have multiple outbound calls, you may need to add some logic to your mock to determine which system it’s simulating. You can use the Endpoint and the soapAction parameters to do this.

You can also influence how your mock should work from your test class. I usually do this by adding static variables to the web service mock class, which I then set in my test method.

Finally, you need to make sure your mock is active. This is done in your test method by calling the setMock method of the test object.

Test.setMock(WebServiceMock.class, new MyWebServiceMock());

You can find a demonstration of this in the DF13_WebService_NETPHP repository on GitHub. Look at the CustomCreditPHP.cls, CustomCreditPHPMock.cls and TestOutbound.cls files in the Force.com/classes folder.

This blog post is a repost from Martin’s old blog called webaholic.

Leave a Reply

Your email address will not be published. Required fields are marked *