I recently wrote about a technique for using a singleton pattern to create a unit test class that could pass mock callout responses titled A Better Way to Unit Test Callouts in Apex Code. When I wrote that article I was still experimenting with using it in real world situations.

For the most part the solution has held up really well and it has allowed me to create some very rich unit tests that are able to test how my code responds to soap faults or exceptions beyond the standard successful response.

I did however come across today a situation where the solution needed to be tweaked. I came upon a situation where I had to test code that made callouts to multiple web services. This became a problem for my current Unit Test class implementation as the property that stores the mock response only allowed for one response. So what I decided to do was to modify the property from an object data type to a map data type.

public Map MockWebServiceResponse {get; set;}

This now allows me to set a key name for the response which as a matter of best practice I have decided to use the function name that will be utilizing the response as the key name.

Here is an example of how this be used in a unit test:

UnitTest oUnitTest = UnitTest.getInstance();

string sXMLMockResponse1 = 'Some response for method1';  
oUnitTest.MockWebServiceResponse.put('method1', sXmlMockResponse1);

string sXmlMockResponse2 = 'Some response for method2';  
oUnitTest.MockWebServiceResponse.put('method2', sXmlMockResponse2);

As shown in the example I am now able to add multiple responses for my callouts so that my tests can respond accordingly. This is especially beneficial when you need to test logic of a web service callout that implements logic based on the results of the previous web service callout.

Here is an example of what the callout method would look like:

public string myCalloutMethod() {  
    string sResponse = '';

    if (Test.isRunningTest()) {
        UnitTest oUnitTest = UnitTest.getInstance();
        sResponse = (string) oUnitTest.MockWebServiceResponse.get('myCalloutMethod');
    }
    else {
        //Perform callout
        sResponse = HttpCallout.Execute(); //Not a real callout method it is just for illustration purposes
    }

    return sResponse;
}

Not too bad, right. It was a minor change with a pretty big impact in my ability to effectively test my callout methods. Let me know how it works out for you if you decide to implement something similar.