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
sudhirn@merunetworks.comsudhirn@merunetworks.com 

Test Class for try and catch block

Hi,

 I modified below trigger by adding catch exception to handle exception scenarious for some reasons test class which i wrote earlier is getting falied can you please suggest me what is the mistake in the trigger and test class to get this failed. 

Trigger
trigger lead_territory_lookup on Lead (After Update) 
{
 if(checkRecursive_LeadTerritory.runOnce())
  {
  
 
String gcountry;
String gstate;
Integer gzip;


 for(Lead l :   Trigger.new){
    gstate = l.State;
    gcountry = l.Country;
     if ( l.postalcode != null)
     { 
      gzip = Integer.valueof(l.postalcode); 
     } 
  }
 
Territory_Lookup__c  TL;

 if ( gcountry  != null )
 {
 Try
 {
if ( trigger.isInsert || trigger.isupdate )
 {

 if ( gcountry != null && gstate != null && gzip != null  )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];
  system.debug('Country & State & Zip');
}

else if ( gcountry != null && gstate != null )
{
 TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
}
    
else if ( gcountry != null && gzip != null)
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];

  system.debug('Country & Zip');
}   

else if ( gcountry != null )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}
else
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}

system.debug('ID Name:' + TL.ID);
system.debug('Country Name:' + TL.Country__c);
system.debug('State Name:' + TL.State__c);
system.debug('Zip Start:' + TL.Zip_Start__c);
system.debug('Zip End:' + TL.Zip_End__c);
 

  List<Lead> leds = new List<Lead>();
   
  for(Lead uld : Trigger.new){                              
   Lead  uleds = new Lead( Id = uld.id,Territory_Lookup__c = TL.ID);
   leds.add(uleds);
  }  
    
   update leds;
    
}   
      
 }


catch (Exception e) {

 
 
List<Lead> leds = new List<Lead>();

if ( gcountry != null && gstate != null )
{
 TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
  

}
 
else
{
  TL = null;
}

  for(Lead uld : Trigger.new){                              
   Lead  uleds = new Lead( Id = uld.id,Territory_Lookup__c = TL.ID);
   leds.add(uleds);
  }  
    
   update leds;

  
  
}  
} 
}
}

Test Class
@isTest
private class lead_territory_lookup_Test {

        static testMethod void protectFields(){
     
                test.startTest();
               
                List<Lead> lstLead =   new List<Lead>{
                          new Lead(Company = 'JohnMiller', LastName = 'Mike', Status = 'Open',
                                   state='Karnataka',country='India',postalcode='5',LeadSource='Community')

                         };
                 insert lstLead;
                 
                List<Territory_Lookup__c> lstTerritory =   new List<Territory_Lookup__c>{ 
                     new Territory_Lookup__c(Country__c = 'India',State__c ='Goa', Zip_End__c = 50, Zip_Start__c = 51)
                     };
                     
                 insert lstTerritory;     
                 
          
                                         

                lstLead[0].LastName = 'Mike';
                lstLead[0].Territory_Lookup__c = lstTerritory[0].id;
                

                update lstLead;
               

                test.stopTest();
        }
}

Thanks
Sudhir
Lars NielsenLars Nielsen
Sudir, can you include a screenshot of the test run so we can see what line(s) and method(s) are having the problem. Since you have custom fields and custom objects it's often faster for an outsider to look at the failure stack to troubleshoot vs trying to reproduce.
sudhirn@merunetworks.comsudhirn@merunetworks.com
I am adding code which didnt not cover and test class error below 

Error MessageSystem.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, NamedAccountOwner: execution of AfterInsert

caused by: System.DmlException: Update failed. First exception on row 0 with id 00Q18000001iVcjEAE; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, lead_territory_lookup: execution of AfterUpdate

caused by: System.QueryException: List has no rows for assignment to SObject

Trigger.lead_territory_lookup: line 111, column 1: []

Trigger.NamedAccountOwner: line 19, column 1: []Stack TraceClass.lead_territory_lookup_Test.protectFields: line 13, column 1


Test Class not covered 
 
else if ( gcountry != null && gstate != null )
{
 TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
}
    
else if ( gcountry != null && gzip != null)
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];

  system.debug('Country & Zip');
}   

else if ( gcountry != null )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}
else
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}

system.debug('ID Name:' + TL.ID);
system.debug('Country Name:' + TL.Country__c);
system.debug('State Name:' + TL.State__c);
system.debug('Zip Start:' + TL.Zip_Start__c);
system.debug('Zip End:' + TL.Zip_End__c);
 

  List<Lead> leds = new List<Lead>();
   
  for(Lead uld : Trigger.new){                              
   Lead  uleds = new Lead( Id = uld.id,Territory_Lookup__c = TL.ID);
   leds.add(uleds);
  }  
    
   update leds;
    
}   
      
 }


catch (Exception e) {

 
 
List<Lead> leds = new List<Lead>();


 TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
  


 


  for(Lead uld : Trigger.new){                              
   Lead  uleds = new Lead( Id = uld.id,Territory_Lookup__c = tl.id);
   leds.add(uleds);
  }  
    
   update leds;


Thanks
Sudhir

Temoc MunozTemoc Munoz
All the lines containing single elements retrieval should be avoided as best practice:
TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c FROM Territory_Lookup__c WHERE Country__c = :gcountry and State__c = :gstate limit 1];

Instead use this:
 
List<Territory_Lookup__c> TLs = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c  FROM Territory_Lookup__c
WHERE Country__c = :gcountry and State__c = :gstate];

if(TLs.size() > 0)
{
   your logic here
}


 
sudhirn@merunetworks.comsudhirn@merunetworks.com
Thanks for you reply I modified the code as you sugget below 

 When I run test class I am getting below error message. 

Error Message System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, contact_territory_lookup: execution of AfterInsert

caused by: System.ListException: List index out of bounds: 0

Trigger.contact_territory_lookup: line 144, column 1: []
Stack Trace Class.Contact_territory_lookup_Test.protectFields: line 26, column 1
trigger contact_territory_lookup on Contact (after Insert, after update) 
{

  if(checkRecursive_contactterritory.runOnce())
  {
  

String gcountry;
String gstate;
Integer gzip;


 for(Contact l :   Trigger.new){
    gstate = l.MailingState;
    gcountry = l.MailingCountry;
     if ( l.MailingPostalCode != null)
     { 
      gzip = Integer.valueof(l.MailingPostalCode); 
     } 
  }
 
//Territory_Lookup__c  TL;
List<Territory_Lookup__c> TL;

  Try
 {

if (trigger.isinsert || trigger.isupdate )
 {

 if ( gcountry != null && gstate != null && gzip != null  )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];
  system.debug('Country & State & Zip');
}

else if ( gcountry != null && gstate != null )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
}
    
else if ( gcountry != null && gzip != null)
{
     TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];

  system.debug('Country & Zip');
}   

else if ( gcountry != null )
{
    TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}
else
{
    TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}

system.debug('ID Name:' + TL[0].ID);
system.debug('Country Name:' + TL[0].Country__c);
system.debug('State Name:' + TL[0].State__c);
system.debug('Zip Start:' + TL[0].Zip_Start__c);
system.debug('Zip End:' + TL[0].Zip_End__c);
 

  List<Contact> leds = new List<Contact>();
   
  for(Contact uld : Trigger.new){                              
   Contact  uleds = new Contact( Id = uld.id,Territory_Lookup__c = TL[0].ID);
   leds.add(uleds);
  }  
    
   update leds;
    
}   
      
 }


catch(DmlException e) {
    System.debug('DmlException caught: ' + e.getMessage());    
} catch(SObjectException e) {
    System.debug('SObjectException caught: ' + e.getMessage());    
}
catch (System.NullPointerException e) {
System.debug('SObjectException caught: ' + e.getMessage());  
}
 

catch (Exception e) {

List<Contact> leds = new List<Contact>();

String chkTLL;

if ( gcountry != null && gstate != null )
{
  TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
}

else if ( gcountry != null )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}

 
for(Contact uld : Trigger.new){                              
   Contact uleds = new Contact( Id = uld.id,Territory_Lookup__c = TL[0].ID);
   leds.add(uleds);
  }  
    
    if(TL.size() > 0)
  {
   update leds;
   }
  }
  
   




} 
 

   

}


Thanks
Sudhir

sudhirn@merunetworks.comsudhirn@merunetworks.com
I was able to fix the issue with below changes. I get only 42% code coverage any suggest how to modify the test class to improve the code coverage. Please suggest. 
 
trigger contact_territory_lookup on Contact (after Insert, after update) 
{

  if(checkRecursive_contactterritory.runOnce())
  {
  

String gcountry;
String gstate;
Integer gzip;


 for(Contact l :   Trigger.new){
    gstate = l.MailingState;
    gcountry = l.MailingCountry;
     if ( l.MailingPostalCode != null)
     { 
      gzip = Integer.valueof(l.MailingPostalCode); 
     } 
  }
 
//Territory_Lookup__c  TL;
List<Territory_Lookup__c> TL;

  Try
 {

if (trigger.isinsert || trigger.isupdate )
 {

 if ( gcountry != null && gstate != null && gzip != null  )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];
  system.debug('Country & State & Zip');
}

else if ( gcountry != null && gstate != null )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
}
    
else if ( gcountry != null && gzip != null)
{
     TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          Zip_Start__c <= :gzip and Zip_End__c >= :gzip limit 1];

  system.debug('Country & Zip');
}   

else if ( gcountry != null )
{
    TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}
else
{
    TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}

system.debug('ID Name:' + TL[0].ID);
system.debug('Country Name:' + TL[0].Country__c);
system.debug('State Name:' + TL[0].State__c);
system.debug('Zip Start:' + TL[0].Zip_Start__c);
system.debug('Zip End:' + TL[0].Zip_End__c);
 

  List<Contact> leds = new List<Contact>();
   
   if(TL.size() > 0)
  {
   
  for(Contact uld : Trigger.new){                              
   Contact  uleds = new Contact( Id = uld.id,Territory_Lookup__c = TL[0].ID);
   leds.add(uleds);
  }  
    
 
   update leds;
    }
}   
      
 }


catch(DmlException e) {
    System.debug('DmlException caught: ' + e.getMessage());    
} catch(SObjectException e) {
    System.debug('SObjectException caught: ' + e.getMessage());    
}
catch (System.NullPointerException e) {
System.debug('SObjectException caught: ' + e.getMessage());  
}
 

catch (Exception e) {

List<Contact> leds = new List<Contact>();

String chkTLL;

if ( gcountry != null && gstate != null )
{
  TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry and
                          State__c = :gstate limit 1];
  system.debug('Country & State');
}

if ( gcountry != null )
{
   TL = [SELECT id,Country__c,State__c,Zip_Start__c,Zip_End__c
                          FROM Territory_Lookup__c
                          WHERE
                          Country__c = :gcountry limit 1];

      system.debug('Country');

}

    if(TL.size() > 0)
  {
for(Contact uld : Trigger.new){                              
   Contact uleds = new Contact( Id = uld.id,Territory_Lookup__c = TL[0].ID);
   leds.add(uleds);
  }  

   update leds;
   }
  }
  
   




} 
 

   

}

Thanks
Sudhir
Lars NielsenLars Nielsen
Sudhir,

One thing to take into consideration is that you have a very large block of code that run inside try/catch blocks. Example - lines 121-155 are not going to execute unless you get stuff that goes way wrong in the try block which is also fairly large.

In my experience, the less logic you can put in the trigger the easier it is troublshoot, maintain, test. 

Right now in order to test lines 121-155 is to force and exception during test exection. Or an alternative might be to put the logic in methods in a TerritoryLookupHelper. Without even really looking at what the code does to try to remove redundency you could simple have two methods

List<Contact> TerritoryLookupHelper.HappyPath(List contacts)
List<Contact> TerritoryLookupHelper.NonHappyPath (List contacts)

Example of method in In a helper class
public static List<Contact> HappyPath(List<Contact> contacts)
	{
		List<Contact> retContacts = new List<Contact>();
		
		return retContacts;
	}

This allows you to call each of them from the test class and bypass try/catch in the trigger. You can literally just call the methods directly with contacts you've created in the test setup and inspect what contacts each method returns and make your assertions.

What this allows you to do is cleanup the trigger code so that all it does is in the try it calls TerritoryLookupHelper.HappyPath and in the catch it calls TerritoryLookupHelper.NonHappyPath.

Of course you want to give the methods meaningful names - don't use my example as is.

Your trigger then ends up with a lot less code and if you ever need to use this logic in other places you abtracted it out of a trigger which is good design. Does that made sense?


 
Temoc MunozTemoc Munoz
I agree with Lars. This is how it will look from a Class Diagram perspective

User-added image

However, If you just want to cover the catch statement, you could try creating a Contact with a non-numerical value:
 
gzip = Integer.valueof(l.MailingPostalCode); // line 018

// And in your test class something like this:
Contact ct = new Contact();
ct.MailingPostalCode = 'AA';

// more code here

If you can provide the code that is not covered, that would be helpful.
sudhirn@merunetworks.comsudhirn@merunetworks.com
Hi Temco,

  Please find the test class below can you please help me to modify the code below
 
@isTest(SeeAllData = true)
private class Contact_territory_lookup_Test {

        static testMethod void protectFields(){
     
                test.startTest();
                
                Account lstAccount = new Account();
                lstAccount.Name='Test Account' ;
                lstAccount.Email_Domain__c = 'samarth.com';
                insert lstAccount;
                
                 List<Territory_Lookup__c> lstTerritory =   new List<Territory_Lookup__c>{ 
                     new Territory_Lookup__c(Country__c = 'India',State__c ='Goa', Zip_End__c = 50, Zip_Start__c = 51)
                     };
                     
                 insert lstTerritory;  
                 
        
                Contact lstContact = new Contact();
                lstContact.FirstName='Test';
                lstContact.LastName='Test';
                lstContact.Accountid= lstAccount.id;
                lstContact.LeadSource = 'Community';
                lstContact.Territory_Lookup__c = lstTerritory[0].id;
                insert lstContact;
               


                lstContact.lastname = 'samarth';
                lstContact.Territory_Lookup__c = lstTerritory[0].id;
                

                update lstContact;
               

                test.stopTest();
        }
}

Thanks
Sudhir
Lars NielsenLars Nielsen
Sudhir, have your re-written any of the trigger so all the logic is not in the trigger or are you still working with the same code you submitted with the question? Temoc gave a great UML diagram. I ask because we can't really see what is failing from the code above. You don't have any debug statements or Asserts that are typical of a test class. 

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_test.htm

For example, after you inser the account on line 11, I'd add a line right after (even just a temporary debug to spit out Salesforce ID of the new account). Do the same after the insert of the Territory. That way when you execute the test, you can look at the full stack trace. 

Can you zip up all the classes/triggers and project and attach it? Just zip the whole source directory along with the objects from Eclipse. If I get time later I'll recreate them in a test org.
Temoc MunozTemoc Munoz
Hi Sudhir,

what is it that you need help with?
Do you need to know how to create the trigger handler?
Test Factory?

Did you also follow Lars' advice?

Thanks