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
Kenji776Kenji776 

Stuck at 62% Coverage

Hey All,
I finished writting my trigger that helps grab info from the web to case form and fill in the case fields as needed, and create/update contacts as needed, but I'm stuck at 62% code coverage and I don't know why. It's only one function, and the test code im providing should get it inside the if statment(s). Any ideas?

Code:
public class WebtoCaseWorkflow 
{
 //This Class will take the information passed in by the web to case form, and basically copy it into
 //the proper fields on the case. Also, it will update contact information if the contact already exists,
 //or create a contact if they do not. 
 
 //Information expected to be passed: Web_First_Name__c, Web_Last_Name__c, SuppliedEmail, SuppliedPhone, CID__c
 //along with the regular case information, eg. subject and description.
 
 //This trigger should not run if the source is Phone, or Email, only if the case is coming from the web.

 public static void QueryAndUpdateCase(Case[] caseitem)
 {
  string AccountIsValid = 'undefined';
  //With the CID passed from the web form, let's try to find the matching account in SF
  for (Case c:caseitem)
  {
   //Make sure this case is coming from the web form before doing anything else.
   if(c.Origin == 'Web')
   {
    //Search for any accounts with the same CID as the one passed in.
             Account[] AccountResult = [SELECT CID__c, Name, Id FROM Account WHERE CID__c = :c.CID__c];
    
      //If we find a match on the CID (which we should, every time)
      //Set the account info for this case.
      
         if(AccountResult.size() > 0)
      {  
     c.AccountId = AccountResult[0].Id;
     AccountIsValid = 'yes';
      }
      
      if(AccountResult.size() < 0)
      {  
     // some kind of error handling should go here. Without a proper account
     // linking we won't be able to add a contact.
     AccountIsValid = 'no';
      }
  
    //Now with the account linked up, let's deal with the contact portion.
 
    //Query for a contact with the same email as the one provided, since email has to be unique.
             Contact[] ContactResult = [SELECT Name, Id, Phone, FirstName, LastName FROM Contact WHERE email = :c.SuppliedEmail];
    
     
     //----------------------------------Found a Contact Match----------------------------------// 
         if(ContactResult.size() > 0)
      {  
       
       //Update the contact record with the information they give us, 
       //since they are giving us updated info, might as well use it.
       for (Contact q:ContactResult)
       {
      q.Phone = c.SuppliedPhone;
      q.FirstName = c.Web_First_Name__c;
      q.LastName = c.Web_Last_Name__c;
     }
     
     //Set the ID of the contact as the one retreived from the query. With just the ID
     //Salesforce can query the contact record and fetch the name, phone number, and email.
     c.ContactId = ContactResult[0].Id;
      }
      
      //--------------------------------Did not find a Contact Match-------------------------//
      if(ContactResult.size() < 1)
      {
       //If the CID they gave was valid, and can be hooked to an account, link the contact
       //to that account as well.
       if(AccountIsValid == 'yes')
       {
        //If the contact does not exist, let's make it using the info provided from the form.
        Contact ContactMake = new Contact(FirstName=c.Web_First_Name__c, LastName=c.Web_Last_Name__c, Email=c.SuppliedEmail, Phone=c.SuppliedPhone, AccountId=AccountResult[0].Id); insert ContactMake;
         CONTACT[] getContactId = [SELECT Id FROM Contact WHERE Email = :c.SuppliedEmail];
         c.ContactId = getContactId[0].Id;
       }
       
       //If the CID they gave us was not valid, and did match to an account, create the contact,
       //but don't attempt to link it to an account since we don't know what account they belong to!
       if(AccountIsValid == 'no')
       {
        //If the contact does not exist, let's make it using the info provided from the form.
        Contact ContactMake = new Contact(FirstName=c.Web_First_Name__c, LastName=c.Web_Last_Name__c, Email=c.SuppliedEmail, Phone=c.SuppliedPhone); insert ContactMake;
         CONTACT[] getContactId = [SELECT Id FROM Contact WHERE Email = :c.SuppliedEmail];
         c.ContactId = getContactId[0].Id;
       }
        
      }
      
      //Okay I think we are done. We have now update the case with both account and contact information
      //that we received from the web form. Hopefully it didn't blow up and die.
   } 
  }
 }
 
 public static testMethod void QueryAndUpdateCaseTest()
 {
   //Create an account and retreive account #
   Account AccountMake = new Account(Name='test123'); insert AccountMake; 
   ACCOUNT[] getAccountId = [SELECT Id FROM Account WHERE name = 'test123'];
   
   //Create a contact that belongs to the account we just made, and retreive the ID
   Contact ContactMake = new Contact(LastName='testJohnson', FirstName='test', Email='frank@frank.com', AccountId=getAccountId[0].Id); insert ContactMake;
   CONTACT[] getContactId = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'testJohnson'];
   
   //Create a case that belongs to the contact we just made, then fetch it's ID.
   Case CaseMake = new Case(ContactId=getContactId[0].Id, Status='open', Problem__c='Other', Origin='Web', Subject='testcase21313213', description='test case of joy', PETE_ID__c='ADY2342342', SuppliedPhone='(345)-352-6244', SuppliedEmail='frank@frank.com', CID__c='141231', SuppliedName='Frank Johnson', SuppliedCompany='test123' ); insert CaseMake;
   CASE[] getCaseId = [SELECT Id, Origin, SuppliedPhone, SuppliedEmail, CID__c, Web_First_Name__c, Web_Last_Name__c, SuppliedCompany  FROM Case WHERE Subject = 'testcase21313213'];

   //Call the main script that autofills those boxes, and pass the array returned from the above query.
    WebtoCaseWorkflow.QueryAndUpdateCase(getCaseId);

 }
}

 

philbophilbo
Hey,

Won't the code inside the conditional
if(ContactResult.size() < 1) {
. . .
}

be skipped altogether, when exercised by your test method? Just eyeballing your queryAndUpdateCase() method,
I would estimate that that code block constitutes more-or-less 38% of the code :) I would guess that your issue boils
down to simply that.

-philbo




Kenji776Kenji776
You may very well be right.
I am new to writting Apex, so how should I go about testing my different conditions. Seeing as that code is needed, do I need to write two different test functions to test each part or what? How would I go about trying to test all my code? Thanks for the help, I really appreciate it.
Kenji776Kenji776
Well I added code to try and test the other if functions, I am up to 68% now. Any tips?

Code:
public class WebtoCaseWorkflow 
{
 //This Class will take the information passed in by the web to case form, and basically copy it into
 //the proper fields on the case. Also, it will update contact information if the contact already exists,
 //or create a contact if they do not. 
 
 //Information expected to be passed: Web_First_Name__c, Web_Last_Name__c, SuppliedEmail, SuppliedPhone, CID__c
 //along with the regular case information, eg. subject and description.
 
 //This trigger should not run if the source is Phone, or Email, only if the case is coming from the web.

 public static void QueryAndUpdateCase(Case[] caseitem)
 {
  string AccountIsValid = 'undefined';
  //With the CID passed from the web form, let's try to find the matching account in SF
  for (Case c:caseitem)
  {
   //Make sure this case is coming from the web form before doing anything else.
   if(c.Origin == 'Web')
   {
    //Search for any accounts with the same CID as the one passed in.
             Account[] AccountResult = [SELECT CID__c, Name, Id FROM Account WHERE CID__c = :c.CID__c];
    
      //If we find a match on the CID (which we should, every time)
      //Set the account info for this case.
      
         if(AccountResult.size() > 0)
      {  
     c.AccountId = AccountResult[0].Id;
     AccountIsValid = 'yes';
      }
      
      if(AccountResult.size() < 0)
      {  
     // some kind of error handling should go here. Without a proper account
     // linking we won't be able to add a contact.
     AccountIsValid = 'no';
      }
  
    //Now with the account linked up, let's deal with the contact portion.
 
    //Query for a contact with the same email as the one provided, since email has to be unique.
             Contact[] ContactResult = [SELECT Name, Id, Phone, FirstName, LastName FROM Contact WHERE email = :c.SuppliedEmail];
    
     
     //----------------------------------Found a Contact Match----------------------------------// 
         if(ContactResult.size() > 0)
      {  
       
       //Update the contact record with the information they give us, 
       //since they are giving us updated info, might as well use it.
       for (Contact q:ContactResult)
       {
      q.Phone = c.SuppliedPhone;
      q.FirstName = c.Web_First_Name__c;
      q.LastName = c.Web_Last_Name__c;
     }
     
     //Set the ID of the contact as the one retreived from the query. With just the ID
     //Salesforce can query the contact record and fetch the name, phone number, and email.
     c.ContactId = ContactResult[0].Id;
      }
      
      //--------------------------------Did not find a Contact Match-------------------------//
      if(ContactResult.size() < 1)
      {
       //If the CID they gave was valid, and can be hooked to an account, link the contact
       //to that account as well.
       if(AccountIsValid == 'yes')
       {
        //If the contact does not exist, let's make it using the info provided from the form.
        Contact ContactMake = new Contact(FirstName=c.Web_First_Name__c, LastName=c.Web_Last_Name__c, Email=c.SuppliedEmail, Phone=c.SuppliedPhone, AccountId=AccountResult[0].Id); insert ContactMake;
         CONTACT[] getContactId = [SELECT Id FROM Contact WHERE Email = :c.SuppliedEmail];
         c.ContactId = getContactId[0].Id;
       }
       
       //If the CID they gave us was not valid, and did match to an account, create the contact,
       //but don't attempt to link it to an account since we don't know what account they belong to!
       if(AccountIsValid == 'no')
       {
        //If the contact does not exist, let's make it using the info provided from the form.
        Contact ContactMake = new Contact(FirstName=c.Web_First_Name__c, LastName=c.Web_Last_Name__c, Email=c.SuppliedEmail, Phone=c.SuppliedPhone); insert ContactMake;
         CONTACT[] getContactId = [SELECT Id FROM Contact WHERE Email = :c.SuppliedEmail];
         c.ContactId = getContactId[0].Id;
       }
        
      }
      
      //Okay I think we are done. We have now update the case with both account and contact information
      //that we received from the web form. Hopefully it didn't blow up and die.
   } 
  }
 }
 
 public static testMethod void QueryAndUpdateCaseTest()
 {
   //Create an account and retreive account #
   Account AccountMake = new Account(Name='test123'); insert AccountMake; 
   ACCOUNT[] getAccountId = [SELECT Id FROM Account WHERE name = 'test123'];
   
   //Create a contact that belongs to the account we just made, and retreive the ID
   Contact ContactMake = new Contact(LastName='testJohnson', FirstName='test', Email='frank@frank.com', AccountId=getAccountId[0].Id); insert ContactMake;
   CONTACT[] getContactId = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'testJohnson'];
   
   //Create a case that belongs to the contact we just made, then fetch it's ID.
   Case CaseMake = new Case(ContactId=getContactId[0].Id, Status='open', Problem__c='Other', Origin='Web', Subject='testcase21313213', description='test case of joy', PETE_ID__c='ADY2342342', SuppliedPhone='(345)-352-6244', SuppliedEmail='frank@frank.com', CID__c='141231', SuppliedName='Frank Johnson', SuppliedCompany='test123' ); insert CaseMake;
   CASE[] getCaseId = [SELECT Id, Origin, SuppliedPhone, SuppliedEmail, Web_First_Name__c, Web_Last_Name__c, SuppliedCompany, CID__c  FROM Case WHERE Subject = 'testcase21313213'];

   //Call the main script that autofills those boxes, and pass the array returned from the above query.
    WebtoCaseWorkflow.QueryAndUpdateCase(getCaseId);
    
    //Create an account and retreive account #
   Account AccountMake1 = new Account(Name='test134523'); insert AccountMake1; 
   ACCOUNT[] getAccountId1 = [SELECT Id FROM Account WHERE name = 'test123'];
   
   //Create a contact that belongs to the account we just made, and retreive the ID
   Contact ContactMake1 = new Contact(LastName='testJo634hnson', FirstName='tes634t', Email='4535frank@frank.com', AccountId=getAccountId[0].Id); insert ContactMake1;
   CONTACT[] getContactId1 = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'testJohnson'];
   
   //Create a case that belongs to the contact we just made, then fetch it's ID.
   Case CaseMake1 = new Case(ContactId=getContactId[0].Id, Status='open', Problem__c='Other', Origin='Web', Subject='testcase21313213', description='test case of joy', PETE_ID__c='ADY2342342', SuppliedPhone='(345)-352-6244', SuppliedEmail='frank@fr435ank.com', CID__c='141231', SuppliedName='Frank Johnson', SuppliedCompany='test123' ); insert CaseMake1;
   CASE[] getCaseId1 = [SELECT Id, Origin, SuppliedPhone, SuppliedEmail, Web_First_Name__c, Web_Last_Name__c, SuppliedCompany, CID__c  FROM Case WHERE Subject = 'testcase21313213'];

   //Call the main script that autofills those boxes, and pass the array returned from the above query.
    WebtoCaseWorkflow.QueryAndUpdateCase(getCaseId1);

 }
}

 

Ron HessRon Hess
i think you are almost there

try this, i just modified the contact email, so that they would not match, this should then fall into the contact < 1 condition



Code:
public static testMethod void QueryAndUpdateCaseTest_2()
 {
   //Create an account and retreive account #
   Account AccountMake = new Account(Name='test123'); insert AccountMake; 
   ACCOUNT[] getAccountId = [SELECT Id FROM Account WHERE name = 'test123'];
   
   //Create a contact that belongs to the account we just made, and retreive the ID
   Contact ContactMake = new Contact(LastName='testJohnson', FirstName='test', Email='frank2@frank.com', AccountId=getAccountId[0].Id); insert ContactMake;
   CONTACT[] getContactId = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'testJohnson'];
   
   //Create a case that belongs to the contact we just made, then fetch it's ID.
   Case CaseMake = new Case(ContactId=getContactId[0].Id, Status='open', Problem__c='Other', Origin='Web', Subject='testcase21313213', description='test case of joy', PETE_ID__c='ADY2342342', SuppliedPhone='(345)-352-6244', SuppliedEmail='frank@frank.com', CID__c='141231', SuppliedName='Frank Johnson', SuppliedCompany='test123' ); insert CaseMake;
   CASE[] getCaseId = [SELECT Id, Origin, SuppliedPhone, SuppliedEmail, CID__c, Web_First_Name__c, Web_Last_Name__c, SuppliedCompany  FROM Case WHERE Subject = 'testcase21313213'];

   //Call the main script that autofills those boxes, and pass the array returned from the above query.
    WebtoCaseWorkflow.QueryAndUpdateCase(getCaseId);

 }

 

philbophilbo
Hey,

In general, yes, you would need to write additional test code to cover the un-exercised remainder of your method.
If it were me, in a case as (relatively) straightforward as this, I would just extend the existing test method, rather than
writing a brand new one.

How are you testing your test method?   I am used to seeing a breakdown of uncovered lines when running
test methods, which makes it easy to know how to extend your tests and increase your coverage.

Best practice, though, is to write your test methods BEFORE your actual 'application' code.  I suspect you're far
from the only developer out there, however, who's put this particular cart before the horse!  :^}

-philbo
Kenji776Kenji776
Okay, I tried Ron's code and got 54% coverage.
The debug log for that run can be found here.
http://www.digitalswordsmen.com/members/Shared/coverage54.txt

Using my code, when getting 68% coverage, the debug log can be found here.
http://www.digitalswordsmen.com/members/Shared/converage68.txt

I'm probably doing things wrong, I'm a total newb trying to teach myself of what scraps of info I can find.


Message Edited by Kenji776 on 03-10-2008 04:33 PM
Ron HessRon Hess
it's not an either / or

place both test methods in your class

i write a new testmethod each time i want to test a different code path, rather than have one testmethod that tries to do it all, just a preference.
Kenji776Kenji776
Ron,
Thanks for your reply. Adding your code, has got me to 68% again, so yeah, it is helping, just gotta figure out whats up with the last 7 %. Here is what my tests look like now.

Code:
 public static testMethod void QueryAndUpdateCaseTest()
 {
   //Create an account and retreive account #
   Account AccountMake = new Account(Name='test123'); insert AccountMake; 
   ACCOUNT[] getAccountId = [SELECT Id FROM Account WHERE name = 'test123'];
   
   //Create a contact that belongs to the account we just made, and retreive the ID
   Contact ContactMake = new Contact(LastName='testJohnson', FirstName='test', Email='frank@frank.com', AccountId=getAccountId[0].Id); insert ContactMake;
   CONTACT[] getContactId = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'testJohnson'];
   
   //Create a case that belongs to the contact we just made, then fetch it's ID.
   Case CaseMake = new Case(ContactId=getContactId[0].Id, Status='open', Problem__c='Other', Origin='Web', Subject='testcase21313213', description='test case of joy', PETE_ID__c='ADY2342342', SuppliedPhone='(345)-352-6244', SuppliedEmail='frank@frank.com', CID__c='141231', SuppliedName='Frank Johnson', SuppliedCompany='test123' ); insert CaseMake;
   CASE[] getCaseId = [SELECT Id, Origin, SuppliedPhone, SuppliedEmail, Web_First_Name__c, Web_Last_Name__c, SuppliedCompany, CID__c  FROM Case WHERE Subject = 'testcase21313213'];

   //Call the main script that autofills those boxes, and pass the array returned from the above query.
    WebtoCaseWorkflow.QueryAndUpdateCase(getCaseId);
 }

 public static testMethod void QueryAndUpdateCaseTest_2()
  {
    //Create an account and retreive account #
    Account AccountMake = new Account(Name='test123'); insert AccountMake; 
    ACCOUNT[] getAccountId = [SELECT Id FROM Account WHERE name = 'test123'];
    
    //Create a contact that belongs to the account we just made, and retreive the ID
    Contact ContactMake = new Contact(LastName='testJohnson', FirstName='test', Email='frank2@frank.com', AccountId=getAccountId[0].Id); insert ContactMake;
    CONTACT[] getContactId = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'testJohnson'];
    
    //Create a case that belongs to the contact we just made, then fetch it's ID.
    Case CaseMake = new Case(ContactId=getContactId[0].Id, Status='open', Problem__c='Other', Origin='Web', Subject='testcase21313213', description='test case of joy', PETE_ID__c='ADY2342342', SuppliedPhone='(345)-352-6244', SuppliedEmail='frank@frank.com', CID__c='141231', SuppliedName='Frank Johnson', SuppliedCompany='test123' ); insert CaseMake;
    CASE[] getCaseId = [SELECT Id, Origin, SuppliedPhone, SuppliedEmail, CID__c, Web_First_Name__c, Web_Last_Name__c, SuppliedCompany  FROM Case WHERE Subject = 'testcase21313213'];
 
    //Call the main script that autofills those boxes, and pass the array returned from the above query.
     WebtoCaseWorkflow.QueryAndUpdateCase(getCaseId);
 
  }

 

Ron HessRon Hess
you will probably need to construct test cases for your code branch:  account is valid yes and no.
Kenji776Kenji776
Wow,
Using the CID generated from the company creation has me up to 74% now.
http://www.digitalswordsmen.com/members/Shared/converage74.txt
There is the log. Gah, just need 1%!