Find your content:

Search form

You are here

Too many callouts 11 while testing using webservicemock interface

 
Share

i have written a test class for a controller in which one of the method makes a callout. This is one single invocation of external SAP webservice. But my debug log shows more than 10 invocation of the webservice but my code actually does not. I already wrote webservice mock implementation class. What could be the issue? If needed i can provide the entire source here.

Source Code:

Generated class from WSDL

//Generated by wsdl2apex

public class sapComDocumentSapSoapFunctionsMcS {
    public class ZGssmwfmHndlEvntrqst00_element {
        public String Dpi2Rtrvlastsaveddata;
        public sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 DpistInpt;
        private String[] Dpi2Rtrvlastsaveddata_type_info = new String[]{'Dpi2Rtrvlastsaveddata','urn:sap-com:document:sap:soap:functions:mc-style',null,'0','1','false'};
        private String[] DpistInpt_type_info = new String[]{'DpistInpt','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style','false','true'};
        private String[] field_order_type_info = new String[]{'Dpi2Rtrvlastsaveddata','DpistInpt'};
    }
    public class Z_GSSMWFM_HNDL_EVNTRQST00 {
        //public String endpoint_x = 'http://xxxnj1:8050/sap/bc/srt/rfc/sap/z_gssmwfm_hndl_evntrqst00/110/z_gssmwfm_hndl_evntrqst00/z_gssmwfm_hndl_evntrqst00';
        public String endpoint_x = 'http://xx.xx.xxx.10:8050/sap/bc/srt/rfc/sap/z_gssmwfm_hndl_evntrqst00/110/z_gssmwfm_hndl_evntrqst00/z_gssmwfm_hndl_evntrqst00';
        public Map<String,String> inputHttpHeaders_x;
        public Map<String,String> outputHttpHeaders_x;
        public String clientCertName_x;
        public String clientCert_x;
        public String clientCertPasswd_x;
        public Integer timeout_x;
        private String[] ns_map_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style', 'sapComDocumentSapSoapFunctionsMcS', 'urn:sap-com:document:sap:rfc:functions', 'sapComDocumentSapRfcFunctions'};
        public sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ZGssmwfmHndlEvntrqst00(String Dpi2Rtrvlastsaveddata,sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 DpistInpt) {
            sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00_element request_x = new sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00_element();
            sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element response_x;
            request_x.Dpi2Rtrvlastsaveddata = Dpi2Rtrvlastsaveddata;
            request_x.DpistInpt = DpistInpt;
            Map<String, sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element> response_map_x = new Map<String, sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element>();
            response_map_x.put('response_x', response_x);
            WebServiceCallout.invoke(
              this,
              request_x,
              response_map_x,
              new String[]{endpoint_x,
              '',
              'urn:sap-com:document:sap:soap:functions:mc-style',
              'ZGssmwfmHndlEvntrqst00',
              'urn:sap-com:document:sap:soap:functions:mc-style',
              'ZGssmwfmHndlEvntrqst00Response',
              'sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element'}
            );
            response_x = response_map_x.get('response_x');
            return response_x;
        }
    }
    public class Bapiret2 {
        public String Type_x;
        public String Id;
        public String Number_x;
        public String Message;
        public String LogNo;
        public String LogMsgNo;
        public String MessageV1;
        public String MessageV2;
        public String MessageV3;
        public String MessageV4;
        public String Parameter;
        public Integer Row;
        public String Field;
        public String System_x;
        private String[] Type_x_type_info = new String[]{'Type','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] Id_type_info = new String[]{'Id','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] Number_x_type_info = new String[]{'Number','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] Message_type_info = new String[]{'Message','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] LogNo_type_info = new String[]{'LogNo','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] LogMsgNo_type_info = new String[]{'LogMsgNo','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] MessageV1_type_info = new String[]{'MessageV1','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] MessageV2_type_info = new String[]{'MessageV2','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] MessageV3_type_info = new String[]{'MessageV3','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] MessageV4_type_info = new String[]{'MessageV4','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] Parameter_type_info = new String[]{'Parameter','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] Row_type_info = new String[]{'Row','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] Field_type_info = new String[]{'Field','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] System_x_type_info = new String[]{'System','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style','false','true'};
        private String[] field_order_type_info = new String[]{'Type_x','Id','Number_x','Message','LogNo','LogMsgNo','MessageV1','MessageV2','MessageV3','MessageV4','Parameter','Row','Field','System_x'};
    }
    public class ZgssmbssDatarcrd01 {
        public String Cdata;
        private String[] Cdata_type_info = new String[]{'Cdata','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style','false','true'};
        private String[] field_order_type_info = new String[]{'Cdata'};
    }
    public class Bapiret2T {
        public sapComDocumentSapSoapFunctionsMcS.Bapiret2[] item;
        private String[] item_type_info = new String[]{'item','urn:sap-com:document:sap:soap:functions:mc-style',null,'0','-1','false'};
        private String[] apex_schema_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style','false','true'};
        private String[] field_order_type_info = new String[]{'item'};
    }
    public class ZgssmbstDatarcrd01 {
        public sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01[] item;
        private String[] item_type_info = new String[]{'item','urn:sap-com:document:sap:soap:functions:mc-style',null,'0','-1','false'};
        private String[] apex_schema_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style','false','true'};
        private String[] field_order_type_info = new String[]{'item'};
    }
    public class ZGssmwfmHndlEvntrqst00Response_element {
        public sapComDocumentSapSoapFunctionsMcS.Bapiret2T DpostMssg;
        public sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 DpostOtpt;
        private String[] DpostMssg_type_info = new String[]{'DpostMssg','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] DpostOtpt_type_info = new String[]{'DpostOtpt','urn:sap-com:document:sap:soap:functions:mc-style',null,'1','1','false'};
        private String[] apex_schema_type_info = new String[]{'urn:sap-com:document:sap:soap:functions:mc-style','false','true'};
        private String[] field_order_type_info = new String[]{'DpostMssg','DpostOtpt'};
    }
}

Controller extension:

    public with sharing class OpenDocumentsController {
    public Boolean displayOpenQuotations {get; set;}
    public string pageSize {get;set;}

    private final Account acct;
    public String CustNo {get;set;}
    public Integer offset { get; set;}
    public Integer NumOf {get;set;}
    public Double TotalAmount {get;set;}


    public List<Quotation> lstQuotations {get;set;}

    private List<String> lstReqData {get;set;}
    private String EventType {get;set;}
    private String InputFields {get;set;}
    private String InputData {get;set;}


   public OpenDocumentsController(ApexPages.StandardController stdController) {
        displayOpenQuotations = true;
        pageSize = '5';

        if (!Test.isRunningTest()) {        
            List<String> addl = new List<String> {};
            addl.add('accountnumber');
            stdController.addFields(addl);
        }
        this.acct = (Account)stdController.getRecord();
        System.debug('acct:'+acct);

        if(CustNo == null) {
            CustNo = acct.AccountNumber; //'1172';
        }
         //offset = 0;
         System.debug('>>>>>>>>>>>>>>>>>offset'+offset);
    }       


//Method to get Open Quotations
    public Quotation[] getOpenQuotations() {
        lstReqData = new List<string> {};
        try {
            if(displayOpenQuotations == true && lstQuotations == null) {
                offset = 0;
                sapComDocumentSapSoapFunctionsMcS.Z_GSSMWFM_HNDL_EVNTRQST00 sap1 = new sapComDocumentSapSoapFunctionsMcS.Z_GSSMWFM_HNDL_EVNTRQST00();       
                Map<List<String>,List<List<String>>> mapSAP = new Map<List<String>,List<List<String>>> {};
                sap1.timeout_x = 90000;
                sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 req = new sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01();      
                List<List<String>> nlstData = new List<List<String>> {};

                lstQuotations = new List<Quotation> {};

                //DATA-TYPE[.]ZGSEVDST_OPENQTA[.]RESPONSE-TYPE=FULL-SETS;ROW-COUNT=1;[.]VBELN[.]AUDAT[.]KUNNR[.]NAME[.]NETWR[.]WAERK[.]ANGDT[.]BNDDT[.]QUNTITY
                //ZGSEVDST_OPENQTA[.]20000039[.]2014-02-05[.]1172[.]CBD Computer Based Design[.]5145.00[.]USD[.]2014-02-05[.]2014-03-06[.]1 of ETO-A002 , 1 of 100-300 , 1 of GTS-14013

                //populating item values

                String EventType = 'EVENT[.]SFDC-OPEN-QUT-GET[.]VERSION[.]0[.]RESPONSE-TYPE[.]FULL-SETS';
                String InputFields = 'SDCAS_T_CUSTLIST[.]'+CustNo;
                String InputData = 'ZGSEVDST_SISINFOINPU[.]'+CustNo;
                lstReqData.add(EventType);
                lstReqData.add(InputFields);
                lstReqData.add(InputData);
                req.item = LoadRequestData(lstReqData);
                sap1.timeout_x = 90000;
                sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ret =  sap1.ZGssmwfmHndlEvntrqst00('',req);
            }
        }Catch(Exception e) {
            Apexpages.Message msg = new Apexpages.Message(Apexpages.Severity.FATAL,'Oops, please try again!!');
            Apexpages.addMessage(msg);
        }
        return lstQuotations;

    }


   public void nextPage() {
   }

   public void previousPage() {
       offset = Math.max(0, offset - 5);
   }

   public void lastPage() {

   }

   public void firstPage() {
       offset = 0;
   }

/*
Wrapper for Open Quotations

Doc Number  Doc Date    Customer Number Customer Name   Amount  CURRENCY    VALID FROM DATE VALID TO DATE   PRODUCTS
Quotation # Quotation Date

[.]AUDAT[.]KUNNR[.]NAME[.]NETWR[.]WAERK[.]ANGDT[.]BNDDT[.]QUNTITY   
*/
 public class Quotation{
        public String DocNumber{get; set;} //VBELN
        public String DocDate{get; set;} //AUDAT
        public String CustomerNumber{get; set;} //KUNRG
        public String CustomerName {get;set;} //NAME
        public String Amount{get; set;} //NETWR    
        public String Curren{get; set;} //WAERK
        public String ValidFromDt{get;set;} //ANGDT
        public String ValidToDt{get;set;} //BNDDT
        public String Product{get;set;} //QUNTITY

    }

   public static List<sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01> LoadRequestData(List<String> lstInput) {
        List<sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01> itm = new List<sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01>();

        //populating item values
        sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01 s1 = new sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01();
        s1.Cdata = 'DEVICE-ID:160000000000000:DEVICE-TYPE:SFDC-CLIENT:APPLICATION-ID:SFDC-SALES';
        itm.add(s1);

        sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01 s2 = new sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01();       
        s2.Cdata = 'NOTATION:ZML:VERSION:0:DELIMITER:[.]';
        itm.add(s2);

        for(String s: lstInput) {
            sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01 s3 = new sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01();
            s3.Cdata = s;
            itm.add(s3);
        }       
        System.debug('item values:'+itm);
        return itm;

    }

    //Method to parse the response from the webservice call
    public static Map<List<String>,List<List<String>>> ParseMultipleResponse(sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ret) {
        System.debug('Inside ParseMultipleResponse');
        List<String> lstHeader = new List<String> {};
        List<String> lstData = new List<String> {};
        List<List<String>> nlstData = new List<List<String>> {};
        Map<List<String>,List<List<String>>> mapSAP = new Map<List<String>,List<List<String>>> {};
        System.debug('response value 1:'+ret.DpostMssg.item);
        System.debug('response value 2:'+ret.DpostOtpt.item);

        //if(ret.DpostMssg.item.isEmpty()) {
            Integer cnt = 0;

            for(sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01 r: ret.DpostOtpt.item) {
                System.debug('cdata value:'+r.Cdata);
                if(cnt == 2) {
                    lstHeader = r.Cdata.split('\\[.]');
                }

                if(cnt >= 3) {
                    lstData = r.Cdata.split('\\[.]');
                    nlstData.add(lstData);
                }
                cnt ++;
            }

            System.debug('lstHeader:'+lstHeader);
            System.debug('lstData:'+lstData);
            System.debug('nlstData:'+nlstData);

        mapSAP.put(lstHeader,nlstData);

        //}
        //System.debug('mapSAP:'+mapSAP);
        return mapSAP;      
    }

    public static String FormatDate(String s) {
        if(s != null || s!= '') {
            String[] dt = s.split('-');
            return dt[1]+'-'+dt[2]+'-'+dt[0];
        } else {
            return '';
        }

    }


    public static Boolean isCurrentMonthYear(String s) {
        if(s!= null && s!= '') {
            String[] dt = s.split('-');
            if(Date.today().month() == Integer.valueOf(dt[1]) && String.valueOf(Date.today().year()) == dt[0]) {
                return true;
            }
        }
        return false;
    }



}

WebserviceMockImpl class:

    @isTest
global class WebServiceMockImpl 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) {

        sapComDocumentSapSoapFunctionsMcS.Z_GSSMWFM_HNDL_EVNTRQST00 sap1 = new sapComDocumentSapSoapFunctionsMcS.Z_GSSMWFM_HNDL_EVNTRQST00();       
        sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 req = new sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01();      

        sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ret =  sap1.ZGssmwfmHndlEvntrqst00('',req);

        sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01 zg = new sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01();
        //zg.Cdata = 'test';

        sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 str = new sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01();

        zg.Cdata = 'DATA-TYPE[.]ZGSEVDST_MATPRICE[.]RESPONSE-TYPE=FULL-SETS;ROW-COUNT=1;[.]KUNNR[.]MATNR[.]KBETR[.]KONWA';
        str.item.add(zg);
        zg.Cdata = 'ZGSEVDST_MATPRICE[.][.]100-100[.]85.00[.]USD';
        str.item.add(zg);



        //sapComDocumentSapSoapFunctionsMcS.ZgssmbssDatarcrd01[] item;
        //item.add(zg);

        //req.item = zg;
        ret.DpostOtpt = str;
        System.debug('return from test:'+ret);
        response.put('response_x', ret.DpostOtpt); 
   }
}

Test class for the controller:

   @isTest

public with sharing class testOpenDocumentsController {
    public static testMethod void testOpenDocuments() {


        Account a = new Account(Name='Tester', AccountNumber='1172');
        insert a;

        Test.startTest();

        ApexPages.StandardController sc = new ApexPages.standardController(a);
        OpenDocumentsController OD = new OpenDocumentsController(sc);
        Test.setMock(WebServiceMock.class, new WebServiceMockImpl()); 
        OD.getOpenQuotations();

        Test.stopTest();
        //System.assertEquals(e.acct, a);
    }

}

Issue:

System.LimitException: Too many callouts: 11

Attribution to: Bforce

Possible Suggestion/Solution #1

I must admit I don't fully know how your mock implementation should look like, but I do think I understand what's going wrong in your version.

A mockservice should "simply" (may not be simple at all) return a response as your service callout is intended to respond. The mockservice class, is not intended to make any call outs (or attempts) - as this would trigger a recursive cycle in a test context where the mockservice is set.

Your mock service contains the line:

sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ret =  sap1.ZGssmwfmHndlEvntrqst00('',req);

This is attempting to perform the webcall out ..

 public sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ZGssmwfmHndlEvntrqst00(String Dpi2Rtrvlastsaveddata, sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 DpistInpt) {
            sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00_element request_x = new sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00_element();
            sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element response_x;
            request_x.Dpi2Rtrvlastsaveddata = Dpi2Rtrvlastsaveddata;
            request_x.DpistInpt = DpistInpt;
            Map < String, sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element > response_map_x = new Map < String, sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element > ();
            response_map_x.put('response_x', response_x);
            WebServiceCallout.invoke(
                this,
                request_x,
                response_map_x,
                new String[] {
                    endpoint_x,
                        '',
                        'urn:sap-com:document:sap:soap:functions:mc-style',
                        'ZGssmwfmHndlEvntrqst00',
                        'urn:sap-com:document:sap:soap:functions:mc-style',
                        'ZGssmwfmHndlEvntrqst00Response',
                        'sapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element'
                }
            );
            response_x = response_map_x.get('response_x');
            return response_x;
        }

which in a test context where this mockservice is set will lauch a new mock instance, which will launch a new webcall out , which will launch a new mock instance, which will launch a new ... etc untill you hit the 11 call outs governor limit.

Update: As the webcall method returns you an ZGssmwfmHndlEvntrqst00Response_element object, your WebServiceMockImpl.doInvoke() method should be COMPOSING such a record and add it to the response map.

public class ZGssmwfmHndlEvntrqst00Response_element {
        public sapComDocumentSapSoapFunctionsMcS.Bapiret2T DpostMssg;
        public sapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 DpostOtpt;
        private String[] DpostMssg_type_info = new String[] {'DpostMssg', 'urn:sap-com:document:sap:soap:functions:mc-style', null, '1', '1', 'false'};
        private String[] DpostOtpt_type_info = new String[] {'DpostOtpt', 'urn:sap-com:document:sap:soap:functions:mc-style', null, '1', '1', 'false'};
        private String[] apex_schema_type_info = new String[] {'urn:sap-com:document:sap:soap:functions:mc-style', 'false', 'true'};
        private String[] field_order_type_info = new String[] {'DpostMssg', 'DpostOtpt'};
    }

As only the DpostMssg and DpostOtpt fields aren't populated, I guess that you should try to put some content in there. I would try to get some real responses from the webservice, either by debugging through apex (not in test mode) or using a tool like SOAPUI. This so that you know what response data from this webservice actually looks like, and so that you can copy a response with content required for your tests in your mockservice.


Attribution to: Samuel De Rycke
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/32374

My Block Status

My Block Content