function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
LogmiLogmi 

testMethod coverage

Hi,
I have created a new vf page (inexperienced and lost) that calls out to an external web services and displays information.  The data received is inserted into two custom tables.  Everything works fine except I cannot create a package because I only have 18% Test Coverage.  I noticed in my "Apex Test Result" a message in the Debug Log that says "Testmethods do not support webservice callouts".  Is that why I'm not getting 100%.  Is there anything I can do to get up to 75% so I can create a package?  Thanks!
Code:
public class LMIController {
  double output;

  public LogMeIn_Computers__c[] getComputers() 
  {
    String groupname = System.currentPageReference().getParameters().get('groupname');
    if(groupname==''){
      return [select Name, rescue__Offline_Since__c, rescue__hostid__c, 
          rescue__group__c,rescue__status__c,
          CreatedDate, CreatedBy.Name, 
          rescue__Remote__c from LogMeIn_Computers__c order by name];
    }
    else{ 
      return [select Name, rescue__Offline_Since__c, rescue__hostid__c, 
          rescue__group__c,rescue__status__c,
          CreatedDate, CreatedBy.Name, 
          rescue__Remote__c from LogMeIn_Computers__c where rescue__groupid__c =:groupname order by name];
    }
  }

  public ITRGroups__c[] getGroups() 
  {
    return [select Name, rescue__Id__c from ITRGroups__c order by name];
  }

  public PageReference newComputer() {
    PageReference pr = Page.lmi_itreach;
    pr.setredirect(true);
    return pr;
  }

  public void refreshComputers() 
  {
    String cred = getCred();
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint('https://secure.logmein.com/ws/hostGetList.asp'+cred); 
    req.setMethod('GET');
    HttpResponse res = h.send(req);

    List<String> rows = new String[1000];
    List<String> afs = new String[1000];
    List<String> urls = new String[1000];
    LogMeIn_Computers__c newHost = new LogMeIn_Computers__c();

    rows = res.getBody().split('\n');

    if(rows[0]=='ERROR:4') {
      return;}

    Integer i = 0;
    
    List<rescue__LogMeIn_Computers__c> allRec = new List<rescue__LogMeIn_Computers__c>();

    for (String tempString : rows) {
      i = i + 1;
      if(i>2){
        afs = tempString.split('\t');
        urls[i] = rGetURL(afs[0]);
      }
    }
    
    i = 0;
    for (String tempString : rows) {
      i = i + 1;
      if(i>2){
        afs = tempString.split('\t');
        if(afs[0]<>''){
          rescue__LogMeIn_Computers__c singleRec = new rescue__LogMeIn_Computers__c();
          if(afs[2]=='0'){
            singleRec.rescue__status__c = 'Offline';}
          else {
            singleRec.rescue__status__c = 'Online';}
          singleRec.name = afs[1];
          singleRec.rescue__hostid__c=afs[0];
          singleRec.rescue__Offline_Since__c=afs[3];
          if(afs[3]==''){
            singleRec.rescue__Offline_Since__c = 'n/a';}
          singleRec.rescue__group__c=findGroup(afs[4]);
          singleRec.rescue__groupid__c=afs[4];
          singleRec.rescue__remote__c=urls[i];
          allRec.add(singleRec);
    upsert allRec rescue__hostid__c;
        }
      }
    }

  }
   
  public string findGroup(String grpId){
    rescue__ITRGroups__c[] ITRGroup = [select name from rescue__ITRGroups__c where rescue__Id__c = :grpId LIMIT 1];
    if(ITRGroup.size()==0){
      List<rescue__ITRGroups__c> groupToCreate = new List<rescue__ITRGroups__c>();
      rescue__ITRGroups__c newgrp = new rescue__ITRGroups__c(name='Group ('+grpId+')', rescue__Id__c = grpId);
      groupToCreate.add(newgrp);
      upsert groupToCreate;
      return 'Group ('+grpId+')';
      }
    return ITRGroup[0].name;
  }

  public string rGetURL(String hostId)
  {
    String cred = getCred();
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint('https://secure.logmein.com/ws/hostConnect.asp'+cred+'&hostid='+hostId); 
    req.setMethod('GET');
    HttpResponse res = h.send(req);
    
    List<String> rows = new String[1000];
    List<String> afs = new String[1000];

    rows = res.getBody().split('\n');
    
    if(rows[0]=='OK'){
      return rows[1].substring(4);}
    else{
      return rows[0];}

  }
    
  public String getCred() 
  {
    rescue__Globals__c r = new rescue__Globals__c();
    r = [select rescue__value__c from rescue__Globals__c where name='psk'];
    String psk = r.rescue__value__c;
    r = [select rescue__value__c from rescue__Globals__c where name='companyid'];
    String companyid= r.rescue__value__c;
    return '—companyid='+companyid+'&psk='+psk;
  }   
}

 
Code:
public class LMIControllerTests {
public static testMethod void testMyController() {

LMIController controller = new LMIController();

controller = new LMIController();
controller.refreshComputers();
}}

 

Drew1815Drew1815
That is correct, you currently can not execute callouts in testMethods.

A workaround is to refactor your Apex so that the line of code that does the request (http send) is as isolated as possible. Basically, just wrap it in its own separate method. And upon response , call yet another refactored method to handle the response processing.

Quickly looking at your code snippet, I would break up the refreshComputers() method into 3 methods.
1. refreshComputers() - this method builds the proper request. Returns an HTTPRequest object.
2. executeCallout(HttpRequest req) - this method takes the HttpRequest as an argument and does the actual HTTP Request. Returns an HTTPResponse request.
3. processResponse(HttpResponse res) - this method processing the response of your HTTP request.

Now you can explicitly call the methods from another apex method. And the testMethod would only execute refreshComputers() and processResponse(). It would not call executeCallout(). This should help get greater code coverage.

One other alternative which doesn't require as much refactoring, is to use a global variable in your Apex Class (boolean) and set it to true when executing a testMethod. Otherwise, it should default to false. And wrap your Http Request/Response logic with an if statement to check if that boolean is true (ie testMethod is executing).

I hope this helps.

Thanks,
Andrew

LogmiLogmi
Thank you Andrew for your response and suggestions.  I was able to get up to 87% and create an install package. 

Message Edited by Logmi on 12-11-2008 07:52 AM