2

I have a future method which sends out two callouts. It looks something like this

@future(callout = true)
static webservice void SendCRMLeadFromTrigger(string leadID){
        //FIRST CALLOUT
        HTTP httpInstance = new HTTP();
        HTTPRequest request = new HTTPRequest();
        request.setEndpoint(endpointURL);
        request.setHeader('Content-Type','text/xml');
        request.setHeader('SOAPAction','xxxxxxxxxxxxx/GetSecurityTokenOperation');
        request.setMethod('POST');
        request.setBody(body);

        string responseBody;
        try{
            HTTPResponse newResponse = httpInstance.send(request);
            responseBody = newResponse.getBody();
           }catch(exception e){}


        //SECOND CALLOUT
        HTTP httpInstance2 = new HTTP();
        HTTPRequest request2 = new HTTPRequest();
        request.setEndpoint(endpointURL2);
        request.setHeader('Content-Type','application/soap+xml');
        request.setHeader('SOAPAction','xxxxxxxxxxxxx/createLead');
        request.setMethod('POST');
        request.setBody(body2);

        string responseBody2;
        try{
            HTTPResponse newResponse2 = httpInstance2.send(request2);
            responseBody2 = newResponse2.getBody();
           }catch(exception e){}
 }

I order to test this method, I created an class which is implementation of MockHttpResponseGenerator class. The class look something like this

public class MockHttpResponseGenerator implements HttpCalloutMock
{
    public HTTPResponse respond(HTTPRequest req) 
    {   
        HttpResponse res = new HttpResponse();

        if(req.getBody().contains('salesforce43')){

            String response='RESPONSE 1';
            res.setHeader('Content-Type', 'text/xml');
            res.setBody(response);

        }else if(req.getBody().contains('<cre:CreateLeadInput>')){

            String response='RESPONSE 2';
            res.setHeader('Content-Type', 'application/soap+xml');
            res.setBody(response);
            }
        res.setStatusCode(200);
        return res;
    }
}

I am calling this class in my test method

public static testmethod void testMultiMockResponse()
{

    Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());

    //create lead
    Lead thisLead = new Lead();
    insert thisLead;

    string leadID = thisLead.Id;
    CalloutClass.SendCRMLeadFromTrigger(leadID);
}

However my test method is not able to cover the response part as there is no HTTP response is null. I am wondering if this is the correct way to test multiple callouts within a method.

In my MockHttpResponseGenerator implementation, I am returning the response based on unique keywords present in each SOAP call.

  • Did you get this to work? I am trying to do something similar. – user8457 May 29 '14 at 23:25
2

Your approach looks basically OK: your mock should generate different responses based on the request data. The code would be clearer and reflect the ideas of SOAP a bit more if you based the conditional logic on the SOAPAction header instead of more obscure values in the request bodies.

But exactly what is wrong is hard to tell from your comments: I suggest you add System.debug calls to all 3 classes and check the values step by step.

  • Thanks @Keith.. I will update the conditional logic with SOAPAction header. So for my understanding sake, when I call the "SendCRMLeadFromTrigger()" in my test method. The two callout response will be returned depending on the callout body condition. Correct? Secondly do I need to write a test code for my HttpCalloutMock implemnetation class as well? – Yash Mehta Apr 22 '14 at 15:50
  • 1
    @YashMehta I'm suggesting you base the return value on the SOAPAction header not the body but yes your mock should simulate both services. You could write test code for your mock, but it will be 100% covered if your other tests cover both cases so it is not mandatory. Personally, I would only write a separate test if the logic in the mock got complicated. – Keith C Apr 22 '14 at 15:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.