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
CTISJH1CTISJH1 

Trouble with Trigger Test

I am unsure what I have done wrong in this test code. It is telling me I have 0% coverage but I feel like it should be telling me 100%. Below is my trigger and test code.

 

Trigger Code:

 

 

trigger storeID on Lead (before insert, before update) {
        
    //variable to hold store number    
    string storeNumber;
    
    //for loop to go through new trigger instances and assign Dealer_Number__c to store variable
    for(Lead l : Trigger.new)        
        storeNumber = l.Dealer_Number__c;
   
    //SOQL query to find account account(store) id from the account(store) that has the same AccountNumber as lead store number
    account a = [SELECT id FROM Account WHERE AccountNumber = :storeNumber];
        
    //for loop to go through trigger and assign account(store) id to lead lookup field Dealer__c
    for(Lead l : Trigger.new)
        l.Dealer__c = a.id; 
              
}

 Test Code:

 

@isTest
private class testLeadStoreIDs {

    static testMethod void myUnitTest() {
            
        account store = new account();
    	store.name = 'test store';
    	store.type = 'other';
    	store.AccountNumber = '123456';
    	insert store;

    	Lead[] leadsToCreate = new Lead[]{};
    	for(Integer x = 0; x<200; x++){
        	Lead l = new Lead();
        	l.LastName = 'last';
        	l.Company = 'test company';
        	l.Status = 'Open';
        	l.Dealer_Number__c = '123456';
    	}

    	//Test.startTest();
    	insert leadsToCreate;
    	//Test.stopTest();
    }
}

 Any advice on how I can get this test code to work would be appreciated. 

 

- Jim Hutcherson

 

 

Best Answer chosen by Admin (Salesforce Developers) 
kiranmutturukiranmutturu

 

 add the inline commented line in your code and try...
@isTest
private class testLeadStoreIDs {
    static testMethod void myUnitTest() {
            
        account store = new account();
     store.name = 'test store';
     store.type = 'other';
     store.AccountNumber = '123456';
     insert store;

     Lead[] leadsToCreate = new Lead[]{};
     for(Integer x = 0; x<200; x++){
         Lead l = new Lead();
         l.LastName = 'last';
         l.Company = 'test company';
         l.Status = 'Open';
         l.Dealer_Number__c = '123456';
 //add this line
 leadsToCreate.add(l);
     }
     //Test.startTest();
     insert leadsToCreate;
     //Test.stopTest();
    }
}

 

All Answers

kiranmutturukiranmutturu

 

 add the inline commented line in your code and try...
@isTest
private class testLeadStoreIDs {
    static testMethod void myUnitTest() {
            
        account store = new account();
     store.name = 'test store';
     store.type = 'other';
     store.AccountNumber = '123456';
     insert store;

     Lead[] leadsToCreate = new Lead[]{};
     for(Integer x = 0; x<200; x++){
         Lead l = new Lead();
         l.LastName = 'last';
         l.Company = 'test company';
         l.Status = 'Open';
         l.Dealer_Number__c = '123456';
 //add this line
 leadsToCreate.add(l);
     }
     //Test.startTest();
     insert leadsToCreate;
     //Test.stopTest();
    }
}

 

This was selected as the best answer
trustchristrustchris

Hi Jim

 

 

Just reviewing your code, you may find that inserting more than once record returns odd results.  In your first loop you are writing Dealer_Number__c values to the same variable and overwriting it each time.

 

In your final for loop, you are updating every lead in trigger.new with the SAME storeNumber variable.

 

You may just want to double check this to avoid unexpected results when your trigger fires in bulk.

 

Cheers

 

Chris

CTISJH1CTISJH1

That was deff part of the problem, I am able to achieve 100% coverage now that I actually add the leads to the array.  Thank you for your input.

 

- Jim Hutcherson

CTISJH1CTISJH1

I see what you mean but am having some trouble bulkifying my code. I know that Maps were the suggested way to handle SOQL queries but I couldn't seem to apply a map to my situation. I am getting this error when my test code inserts more than 1 lead.

 

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, storeID: execution of BeforeInsert caused by: System.ListException: List index out of bounds: 2 Trigger.storeID: line 22, column 25: []

 

Below is my revised trigger but I have done something wrong.

 

trigger storeID on Lead (before insert, before update) {
            
    // List to hold store numbers for all new trigger instances    
    List<string> storeNumber = new List<string>();     

    // For loop to go through new trigger instances and assign Dealer_Number__c to store variable
    for(Lead l : Trigger.new)        
        storeNumber.add(l.Dealer_Number__c);
   
    // SOQL query to find account account(store) id from the account(store) that has the same AccountNumber as lead store number    
    List<Account> acct = [SELECT Id FROM Account where AccountNumber IN :storeNumber];
    
    // Finds the size of acct list
    Integer size = acct.size();
        
    // For loop to go through trigger and assign account(store) id to lead lookup field Dealer__c
    
    integer x = 0;
    
    do {
        for(Lead l : Trigger.new){                    
            Account a = acct.get(x);
            l.Dealer__c = a.id;
            x++;                         
        }
    } while ( x < size);
}

 

I rushed this response a bit so if this ends up being a bad logic issue I apologize in advance. I can get 100% coverage with no error message if I insert just one lead in the test code. When I introduce more than 1 lead I get the above error but I still recieve 100% test coverage score. I am hesistant to deploy this to production until I can be sure I won't have an issue waiting to show it self.

 

 

Also, I was hoping someone might be able to provide me with a practical example of when more than 1 lead would be inserted at a time. 

 

 

- Jim Hutcherson


 

trustchristrustchris

Try this:

 

 

trigger storeID on Lead (before insert, before update) {
            
// List to hold store numbers for all new trigger instances    
List<string> storeNumber = new List<string>();     

// For loop to go through new trigger instances and assign Dealer_Number__c to store variable
for(Lead l : Trigger.new)        
	storeNumber.add(l.Dealer_Number__c);

//create a map to holf the store number and account id
Map<String, Id> accMap = new Map<String, Id>();

for(Account a:  [SELECT Id FROM Account where AccountNumber IN :storeNumber]){
	//loop through the list and create a map with the storeNumber as the id.
	accMap.put(a.AccountNumber, a.Id);
}
    
        
for(Lead l : Trigger.new)  {
	//look up each Dealer Number from the map, and assign the value to the Dealer__c field.
	l.Dealer__c = accMap.get(l.Dealer_Number__c);
	}    
    
}

 

 

Have created a map with StoreNumber(Key) and AccountId(Value).  Then just loop through the trigger records and lookup the appropriate key from the map and update the Lead.

 

An example of multiple records updating at one time - inserting records using the dataloader, or upload wizard.  Integration with other 3rd party applications that use the api to mass update records.

 

I haven't compiled the code, but give it a go and see how you get on.  It could benefit from some error handling incase an AccountNumber or store number is null, but should get you through bulk testing.

 

Cheers

 

Chris

CTISJH1CTISJH1

Thanks Chris! You put me in the right direction and with some trial and error I have something that seems to be working better. I ended up using a map like you suggested and that works great. Here is my code.

 

 

trigger storeID on Lead (before insert, before update) {
                        
    // For loop to go through new trigger instances and assign Dealer_Number__c to storeNumber List
    List<string> storeNumber = new List<string>();
    for(Lead l : Trigger.new)        
        storeNumber.add(l.Dealer_Number__c);
        
    //Map to hold AccountNumber and corresponding account              
    Map<String, Account> accounts = new Map<String, Account>();    
    List<Account> accts = [SELECT Id, AccountNumber FROM Account where AccountNumber IN :storeNumber];    
    for(account a : accts){    
        accounts.put(a.AccountNumber, a);
    }
     
    //Loop to assign account id to lead field Dealer__c
    for(Lead l : Trigger.new){
        account act = accounts.get(l.Dealer_Number__c);
        l.Dealer__c = act.id;
    }   
                               
}

 

I am going to work on catching any null fields next. Thanks again!