+ Start a Discussion
virkvirk 

Executing a test method to test a trigger calling another method using webservice callout

Hello,

I want to test a trigger to calculate Location latitude and location longitude for a contact which is calling another method which is using webservice callout to calculate these parameters. However in my code I am not using this callout if the test is running and passing hard coded response instead. 

here is my code:

@future(callout=true)
    public static void GeoCodeAddress(id contactid)
    {
        // format the string for the Bing Maps engine
        shouldIRun.stopTrigger();
       
        String FormattedAddress;
        try
        {
        FormattedAddress = BuildAddressString(contactId);
        }
        catch (exception e)
        {
            return;
        }

        String key = 'AqiKi39Ge5Y57NRLwSrXTft8MU8UIHH5BR-lPz3tYyNBwU6Fzf-lSIjpxV7C5utk';//getAPIKey();
        integer n = 0;
        if (!String.isBlank(FormattedAddress)) {
           
            string GeoCodeRequestURL = 'http://dev.virtualearth.net/REST/v1/Locations?'+ FormattedAddress + '&key=' + key;// + '&maxResults=1';
            if (test.IsRunningTest() == false) {
           
            // Setup and make the HTTP callout
            HttpRequest GeoCodeRequest = new HttpRequest();
            Http GeoCodeHttp = new Http();              
            GeoCodeRequest.setMethod('GET');           
            GeoCodeRequest.setEndpoint(GeoCodeRequestURL);
            GeoCodeRequest.setTimeout(120000);
           
                 HttpResponse GeoCodeResponse = GeoCodeHttp.send(GeoCodeRequest);
                 ParseGeoCodeJSONReponse(GeoCodeResponse.getBody(), contactId);
               
             //CurrentGeoCodeResult = ParseGeoCodeJSONReponse(GeoCodeResponse.getBody()); 
             } else {
                 System.debug('Tst method');
                 String GeoCodeResponse1 = '{"Point": { "coordinates": [ -86.8142376, 33.5195411, 0 ] } } ';
                 ParseGeoCodeJSONReponse(GeoCodeResponse1, contactId);
                 //CurrentGeoCodeResult = ParseGeoCodeJSONReponse(GeoCodeResponse);           
             } // Istest == false   
       }
    } // GeoCodeAddress

    /**
     * Builds the string for use in the URL from the address of the given contact
     * @param contactid Id of the contact whose address we want to build
     * @return String
     */
   private static string BuildAddressString(id contactId) {
   
      // Example String: /US/WA/98052/Redmond/1%20Microsoft%20Way
      // Note that 1+Microsoft+Way is techinically in the UTF-8 spec the same as above
      // however, Microsoft doesn't follow that and must have %20 so we can't use urlEncode function
      contact c = [SELECT MailingCity,MailingCountry,MailingPostalCode,MailingState,MailingStreet,Location__Latitude__s,Location__Longitude__s FROM contact WHERE id =: contactId];
      // create an address string
        String Address = '';      
         if(c.MailingCity != null){
           if(c.MailingCountry != null) {
               c.MailingCountry = c.MailingCountry.Replace(' ', '%20');
               Address += 'CountryRegion=' + c.MailingCountry;        
            } else {
               Address = 'CountryRegion=' + 'FR';
           }// Country
           if(c.MailingCity != null){
               c.MailingCity = c.MailingCity.Replace(' ', '%20');
               Address += '&locality=' + c.MailingCity;
           } // Postal Code
           if(c.MailingPostalCode != null) {
               c.MailingPostalCode = c.MailingPostalCode.Replace(' ', '%20');
                Address += '&postalCode=' + c.MailingPostalCode;
           } // City
                 
           if(c.MailingStreet != null) {
             // Bing has some issues:
             //     1. It wants %20 instead of spaces
             //     2. It won't geocode PO Boxes to the city - so remove them
             //     3. It doesn't like the # symbol in the address so remove them
             //     4. It won't process an address than ends in a period
          
               c.MailingStreet = c.MailingStreet.Replace(' ', '%20');                             
               c.MailingStreet = c.MailingStreet.toUpperCase();
               c.MailingStreet = c.MailingStreet.Replace('P.O. BOX', '');
               c.MailingStreet = c.MailingStreet.Replace('#', '');
          
               // Bing has problems with addresses that end in periods, so just remove them
               if (c.MailingStreet.EndsWith('.') == true ) {
                   c.MailingStreet = c.MailingStreet.RemoveEnd('.');
               }
                   Address += '&addressLine=' + c.MailingStreet;                      
               } // Street   
                // remove any line breaks
                Address = Address.replace('\n',' ');
                Address = Address.replace('\r',' ');                   
        }                       
        return Address;
    }
   
    /**
     * Parses a geocoded response and updates the given contact with these informations
     * @param ResponseBody A json response to parse
     * @param contactId Id of the contact we want to update
     * @return void
     */
    private static void ParseGeoCodeJSONReponse(String ResponseBody, Id contactId) {

        //GeoCodeResult ReturnGeoCodeResult = IncomingGeoCodeResult;
         
       JSONParser parser = JSON.createParser(ResponseBody);
       
       String StatusResult = '';
       
       contact c = [SELECT Location__Latitude__s,Location__Longitude__s FROM contact WHERE id =: contactId];
        
       while (parser.nextToken() != null) {
          if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
              (parser.getText() == 'statusDescription')) {
                  parser.nextToken();
                  StatusResult = parser.getText();
                  //ReturnGeoCodeResult.Status = StatusResult;
                  break;
          } // if status         
       }  // loop thru looking for Status
    
        if (test.IsRunningTest() == true)
            StatusResult='OK';
       
            if (StatusResult == 'OK') {
                // parse the results from the start again
                parser = JSON.createParser(ResponseBody);
                while (parser.nextToken() != null) {
                  if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                  (parser.getText() == 'coordinates')) {
                      // skip to the [
                      parser.nextToken();
                      // now get the first value
                      parser.nextToken();
                      c.Location__Latitude__s = parser.getDoubleValue();                         
                      // now get the 2nd value
                      parser.nextToken();                                                                                                                 
                      c.Location__Longitude__s = parser.getDoubleValue();
                  } // if point   
                } // while (parser.nextToken() != null)
             } 
         if (test.IsRunningTest() == false) {
              update c;
         }
    }
       
}


but test fails saying that "Methods defined as TestMethod do not support Web service callouts, test skipped". In developer console this method finishes properly and after it enters in to another tirgger inside managed package and fails. Please help if someone has any idea. Is there any way to avoid triggers inside managed package from running on execution of test method testing trigger on the same object?

Thanks in advance.
Eli Flores, SFDC DevEli Flores, SFDC Dev
You'll want to create a custom class with the WebServiceMock interface. This should get you started:

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_callouts_wsdl2apex_testing.htm

That should get you started. If it's a rest-based service, you'll want to check out HttpCalloutMockInterface instead.